Authentication
Login and registration APIs and UI flows for the Platform
Overview
The Platform uses NextAuth v5 with a Credentials provider for email/password auth. Users can:
- Register via
POST /api/auth/register— creates a user and a default organization - Log in via NextAuth — session is JWT-based with a 7-day max age
After login, users are redirected to the dashboard (/). Session contains user.id, user.name, user.email.
Session Info
All authenticated sessions use JWT tokens with a 7-day maximum age. Session data includes user.id, user.name, and user.email.
Registration API
Endpoint: POST /api/auth/register
Content-Type: application/json
Creates a new user account and a default organization ("My Organization"). Does not sign the user in; they must log in after registering.
Request Body
| Field | Type | Required | Validation |
|---|---|---|---|
name | string | Yes | Min 1 character |
email | string | Yes | Valid email format |
password | string | Yes | Min 6 characters |
curl -X POST https://your-app.com/api/auth/register \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Doe",
"email": "jane@example.com",
"password": "secret123"
}'const response = await fetch('/api/auth/register', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'Jane Doe',
email: 'jane@example.com',
password: 'secret123',
}),
});
const data = await response.json();
console.log(data.user.id); // "cm4abc123..."import requests
response = requests.post(
"https://your-app.com/api/auth/register",
json={
"name": "Jane Doe",
"email": "jane@example.com",
"password": "secret123",
},
)
data = response.json()
print(data["user"]["id"]) # "cm4abc123..."Success Response
Status: 201 Created
{
"user": {
"id": "cm4abc123...",
"name": "Jane Doe",
"email": "jane@example.com"
}
}Error Responses
| Status | Condition | Body |
|---|---|---|
400 | Validation failed (Zod) | { "message": "Validation failed", "errors": [{ "path": ["email"], "message": "Invalid email address" }] } |
409 | Email already registered | { "message": "Email already registered" } |
500 | Server error | { "message": "Internal server error" } |
Validation Rules
- name:
string, min length 1 —"Name is required" - email:
string, valid email —"Invalid email address" - password:
string, min 6 characters —"Password must be at least 6 characters"
Side Effects
- Inserts into
userstable (name, email, bcrypt-hashed password) - Creates one row in
organizationswithname: "My Organization",ownerId: user.id, and a uniqueslug
Login (NextAuth)
Login is handled by NextAuth, not a standalone REST endpoint. The UI calls signIn('credentials', ...) which triggers the NextAuth credentials callback.
Credentials
| Field | Type | Required |
|---|---|---|
email | string | Yes |
password | string | Yes |
import { signIn } from 'next-auth/react';
const result = await signIn('credentials', {
email: 'jane@example.com',
password: 'secret123',
redirect: false,
});
if (result?.ok) {
// Redirect to dashboard
router.push('/');
} else {
// Show error message
console.error('Invalid credentials');
}Success
JWT Session Created
NextAuth creates a JWT session with a max age of 7 days containing user.id, user.name, user.email.
Organization Check
If the user has no organization, the server automatically creates "My Organization" on first sign-in.
Redirect
User is redirected to / (dashboard).
Failure
Error Handling
Invalid email or password: authorize() returns null → client receives result.ok === false. The client checks signIn(..., { redirect: false }) and then result?.ok.
UI/UX Flows
Registration Flow
Route: /register
Layout
Split screen design with image panel + gradient overlay on the left, form on the right. Includes logo, language switcher (EN/AR), and RTL support.
Form Fields
- Name: text input with User icon, required
- Email: email input with Mail icon, required
- Password: password input with Lock icon, min 6 chars, show/hide toggle
Submit & Redirect
On success: redirect to /login. On error: display error message (e.g. "Email already registered").
Login Flow
Route: /login
Layout
Same AuthLayout with different hero image. Logo and language switcher included.
Form Fields
- Email: email input with Mail icon
- Password: password input with show/hide toggle
Submit & Redirect
On success: router.push('/') to dashboard. On failure: show "Invalid credentials" error.
Summary
| Action | API / Mechanism | Request Body | Success Result |
|---|---|---|---|
| Register | POST /api/auth/register | name, email, password | 201 + user; redirect to /login |
| Log in | NextAuth credentials | email, password | Session created; redirect to / |
All auth requests use the same Platform base URL. No API key is needed for these endpoints — registration is public, and login uses cookies/session.