# SecNex Auth Login A Next.js 15 application for authentication with SecNex. The application uses Server Actions for login/logout and Route Handlers for session checks. Authentication tokens are managed via HTTP-only cookies. ## Features - **Login Form** - Username/password authentication with form validation - **OAuth Authorization Flow** - `/authorize` endpoint for third-party app authorization - **Session Management** - Token validation and automatic cleanup - **Social Login Buttons** - GitHub and Google OAuth buttons (UI only) - **Responsive UI** - Built with shadcn/ui components - **Toast Notifications** - User feedback using Sonner ## Project Structure ``` auth-login/ ├── app/ │ ├── api/ │ │ ├── logout/ │ │ │ └── route.tsx # Route Handler for logout │ │ └── session/ │ │ └── route.ts # Route Handler for session check │ ├── authorize/ │ │ └── page.tsx # OAuth authorization page │ ├── layout.tsx # Root layout with fonts │ └── page.tsx # Home page (Login / Success) ├── components/ │ ├── core/ │ │ ├── login-form.tsx # Login form components (Client Components) │ │ ├── authorize.tsx # OAuth authorization component │ │ ├── social-login-button.tsx │ │ └── loading.tsx # Loading spinner component │ ├── server/ │ │ └── login.tsx # Server Actions for login │ └── ui/ # UI components (shadcn/ui) ├── lib/ │ └── utils.ts # Utility functions └── permissions.json # OAuth scope permissions ``` ## Technical Details ### Route Handlers vs Server Actions In Next.js 15, cookies can only be modified in the following contexts: - **Route Handlers** (API routes under `app/api/`) - **Server Actions** with `"use server"` directive **Key Difference:** - Route Handlers can ALWAYS modify cookies - Server Actions CANNOT modify cookies when called from a Server Component ### Architecture Decisions | Operation | Type | Reason | |-----------|------|--------| | Login | Server Action | Called from Client Components | | Session Check | Route Handler | Called from Server Component, needs cookie deletion ability | | Logout | Route Handler | Called from Client Component via fetch | ### Cookie Deletion in Route Handler **Problem:** The original code attempted to delete cookies in a Server Action called from a Server Component, resulting in: ``` Error: Cookies can only be modified in a Server Action or Route Handler. ``` **Solution:** The session check was moved to a Route Handler (`app/api/session/route.ts`). Route Handlers always have access to cookie modification, regardless of the caller. ## Getting Started ### Prerequisites - Node.js 18+ - pnpm ### Environment Variables Create a `.env.local` file in the root directory: ```bash SECNEX_AUTH_API_HOST=http://localhost:3001 SECNEX_AUTH_API_KEY=your_api_key_here ``` ### Installation ```bash pnpm install ``` ### Development Server ```bash pnpm dev ``` The application will be available at [http://localhost:3000](http://localhost:3000). ### Build ```bash pnpm build ``` ### Production ```bash pnpm start ``` ## How It Works ### Login Flow 1. User enters username and password 2. `login()` Server Action is called 3. Request to SecNex API (`/login`) 4. On success: Token is stored in HTTP-only cookie 5. Page is refreshed ### Session Check (via Route Handler) 1. Server Component checks if token exists 2. GET request to `/api/session` 3. Route Handler validates token with SecNex API (`/session/info`) 4. On invalid token: Cookie is deleted directly 5. Result is returned ### Logout Flow 1. `GET /api/logout` is called 2. Request to SecNex API (`/logout`) 3. Cookie is deleted ### OAuth Authorization Flow 1. User is redirected to `/authorize` with query parameters: - `client_id` - The client application identifier - `redirect_uri` - The URI to redirect after authorization - `response_type` - The response type (default: "code") - `scope` - Requested permissions (default: "profile email") 2. User must be logged in (otherwise redirected to `/`) 3. Authorization page shows: - Application name and URL - User information - Requested permissions (from `permissions.json`) 4. User can authorize or deny the request ## API Endpoints ### Server Actions #### `login(username, password)` Performs login and stores the token in a cookie. ```typescript const response = await login("user", "password"); // { success: boolean, message: string, token?: string } ``` ### Route Handlers #### `GET /api/session` Validates the token and returns session information. Automatically deletes the cookie on invalid token. ```typescript const response = await fetch("/api/session"); const data = await response.json(); // { success: boolean, message: string, sessionInfo?: { username, email, role } } ``` #### `GET /api/logout` Logs out the user and deletes the token. ```typescript const response = await fetch("/api/logout"); const data = await response.json(); // { success: boolean, message: string } ``` ## Components ### `LoginContainer` Displays the login form. ```tsx ``` ### `LoginSuccessContainer` Displays the success page after login. ```tsx ``` ### `AuthorizeContainer` Displays the OAuth authorization page. ```tsx ``` ## Permissions The `permissions.json` file defines OAuth scope permissions: ```json { "profile": { "name": "Profile Information", "description": "View your name and profile picture" }, "email": { "name": "Email Address", "description": "View your email address" } } ``` ## Important Notes - Server Actions use `"use server"` directive - Route Handlers allow cookie modification from Server Components - Cookies are HTTP-only for additional security - The SecNex API must be running at the configured `SECNEX_AUTH_API_HOST` - API credentials should be stored in environment variables (not hardcoded) ## Tech Stack - **Next.js 15** - React framework - **React 19** - UI library - **TypeScript** - Type safety - **Tailwind CSS** - Styling - **shadcn/ui** - UI components - **Radix UI** - Headless UI primitives - **React Hook Form** - Form management - **Zod** - Schema validation - **Sonner** - Toast notifications - **Tabler Icons** - Icon library ## Deployment ### Vercel The easiest way to deploy is using the Vercel platform: [https://vercel.com/new](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) For more information, see the [Next.js Deployment Documentation](https://nextjs.org/docs/app/building-your-application/deploying). ### Environment Variables Make sure to set the following environment variables in your deployment: - `SECNEX_AUTH_API_HOST` - Your SecNex API host URL - `SECNEX_AUTH_API_KEY` - Your SecNex API key ## License MIT