init: Initial commit

This commit is contained in:
Björn Benouarets
2026-01-19 08:42:07 +01:00
parent 1a47930d75
commit 74232ad2d2
74 changed files with 9822 additions and 98 deletions

285
README.md
View File

@@ -1,36 +1,281 @@
This is a [Next.js](https://nextjs.org) project bootstrapped with [`create-next-app`](https://nextjs.org/docs/app/api-reference/cli/create-next-app).
# 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
First, run the development server:
### Prerequisites
- Node.js 18+
- pnpm
### Environment Variables
Create a `.env.local` file in the root directory:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
SECNEX_API_HOST=http://localhost:3001
SECNEX_API_KEY=your_api_key_here
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
### Installation
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
```bash
pnpm install
```
This project uses [`next/font`](https://nextjs.org/docs/app/building-your-application/optimizing/fonts) to automatically optimize and load [Geist](https://vercel.com/font), a new font family for Vercel.
### Development Server
## Learn More
```bash
pnpm dev
```
To learn more about Next.js, take a look at the following resources:
The application will be available at [http://localhost:3000](http://localhost:3000).
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
### Build
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js) - your feedback and contributions are welcome!
```bash
pnpm build
```
## Deploy on Vercel
### Production
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
```bash
pnpm start
```
Check out our [Next.js deployment documentation](https://nextjs.org/docs/app/building-your-application/deploying) for more details.
## 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
<LoginContainer applicationName="SecNex" applicationLogo="/logo.png" />
```
### `LoginSuccessContainer`
Displays the success page after login.
```tsx
<LoginSuccessContainer
applicationName="SecNex"
applicationLogo="/logo.png"
/>
```
### `AuthorizeContainer`
Displays the OAuth authorization page.
```tsx
<AuthorizeContainer
applicationName="My App"
applicationUrl="https://example.com"
applicationLogo="/app-logo.png"
client_id="abc123"
redirect_uri="https://example.com/callback"
response_type="code"
scope="profile email"
/>
```
## 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_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_API_HOST` - Your SecNex API host URL
- `SECNEX_API_KEY` - Your SecNex API key
## License
MIT