Authentication API
Complete reference for user authentication endpoints using Supabase Auth with JWT token management.
๐ Authentication Methods
The API supports two authentication methods:
- Supabase Auth - Primary authentication system
- Legacy Admin Tokens - Backward compatibility for admin endpoints
๐ก Endpoints
Sign Up
Register a new user account.
Endpoint: POST /api/auth/signup
Request Body:
{
"email": "user@example.com",
"password": "securepassword123",
"name": "John Doe"
}Validation:
email: Valid email format (required)password: Minimum 6 characters (required)name: Minimum 2 characters (required)
Response: 201 Created
{
"success": true,
"data": {
"user": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "user@example.com",
"name": "John Doe",
"createdAt": "2025-12-18T10:00:00.000Z"
},
"session": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "v1.MJBbF...",
"expiresIn": 3600,
"tokenType": "bearer"
}
},
"message": "User registered successfully"
}Error Responses:
// 400 Bad Request - Validation Error
{
"success": false,
"error": "Validation failed",
"details": {
"email": ["Invalid email format"],
"password": ["Password must be at least 6 characters"]
}
}
// 409 Conflict - User Already Exists
{
"success": false,
"error": "User with this email already exists"
}
// 500 Internal Server Error
{
"success": false,
"error": "Failed to register user"
}Example:
curl -X POST http://localhost:3001/api/auth/signup \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "mypassword123",
"name": "John Doe"
}'Sign In
Authenticate with email and password.
Endpoint: POST /api/auth/signin
Request Body:
{
"email": "user@example.com",
"password": "securepassword123"
}Response: 200 OK
{
"success": true,
"data": {
"user": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "user@example.com",
"name": "John Doe",
"lastLogin": "2025-12-18T10:00:00.000Z"
},
"session": {
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"refreshToken": "v1.MJBbF...",
"expiresIn": 3600,
"tokenType": "bearer"
}
},
"message": "Signed in successfully"
}Error Responses:
// 401 Unauthorized - Invalid Credentials
{
"success": false,
"error": "Invalid email or password"
}
// 400 Bad Request
{
"success": false,
"error": "Email and password are required"
}Example:
curl -X POST http://localhost:3001/api/auth/signin \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com",
"password": "mypassword123"
}'Sign Out
End the current user session.
Endpoint: POST /api/auth/signout
Headers:
Authorization: Bearer <access_token>Response: 200 OK
{
"success": true,
"message": "Signed out successfully"
}Error Responses:
// 401 Unauthorized
{
"success": false,
"error": "No active session"
}Example:
curl -X POST http://localhost:3001/api/auth/signout \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."Reset Password
Request a password reset email.
Endpoint: POST /api/auth/reset-password
Request Body:
{
"email": "user@example.com"
}Response: 200 OK
{
"success": true,
"message": "Password reset email sent. Check your inbox."
}Error Responses:
// 400 Bad Request
{
"success": false,
"error": "Email is required"
}
// 404 Not Found
{
"success": false,
"error": "No user found with this email"
}Example:
curl -X POST http://localhost:3001/api/auth/reset-password \
-H "Content-Type: application/json" \
-d '{
"email": "john@example.com"
}'Update Password
Update password using reset token.
Endpoint: POST /api/auth/update-password
Request Body:
{
"token": "reset_token_from_email",
"newPassword": "newsecurepassword456"
}Response: 200 OK
{
"success": true,
"message": "Password updated successfully"
}Error Responses:
// 400 Bad Request - Invalid Token
{
"success": false,
"error": "Invalid or expired reset token"
}
// 400 Bad Request - Weak Password
{
"success": false,
"error": "Password must be at least 6 characters"
}Example:
curl -X POST http://localhost:3001/api/auth/update-password \
-H "Content-Type: application/json" \
-d '{
"token": "abc123...",
"newPassword": "newpassword123"
}'Get Current User
Retrieve authenticated user's profile.
Endpoint: GET /api/auth/me
Headers:
Authorization: Bearer <access_token>Response: 200 OK
{
"success": true,
"data": {
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"email": "user@example.com",
"name": "John Doe",
"createdAt": "2025-12-01T10:00:00.000Z",
"lastLogin": "2025-12-18T10:00:00.000Z",
"roles": ["user"]
}
}Error Responses:
// 401 Unauthorized
{
"success": false,
"error": "Authentication required"
}Example:
curl http://localhost:3001/api/auth/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."Link Social Account
Link social authentication providers.
Endpoint: POST /api/auth/link
Headers:
Authorization: Bearer <access_token>Request Body:
{
"provider": "google",
"token": "google_oauth_token"
}Response: 200 OK
{
"success": true,
"message": "Account linked successfully"
}๐ JWT Token Usage
Access Tokens
Purpose: Authenticate API requests
Lifetime: 1 hour (3600 seconds)
Storage: Client-side (memory or secure storage)
Refresh Tokens
Purpose: Obtain new access tokens
Lifetime: 30 days
Storage: HttpOnly cookie (recommended)
Token Refresh Flow
sequenceDiagram
participant Client
participant API
participant Supabase
Client->>API: Request with expired access token
API-->>Client: 401 Unauthorized
Client->>API: POST /api/auth/refresh (with refresh token)
API->>Supabase: Validate refresh token
Supabase-->>API: New access token
API-->>Client: New session tokens
Client->>API: Retry request with new access token
API-->>Client: Success responseUsing Tokens in Requests
Header Format:
Authorization: Bearer <access_token>Example with curl:
curl http://localhost:3001/api/users/me \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."Example with JavaScript:
const response = await fetch('http://localhost:3001/api/users/me', {
headers: {
'Authorization': `Bearer ${accessToken}`,
'Content-Type': 'application/json',
},
});๐ก๏ธ Security Best Practices
Password Requirements
- Minimum 6 characters
- Mix of uppercase, lowercase, numbers (recommended)
- No common passwords
- No personal information
Token Security
- Never expose tokens in URLs
- Store access tokens securely (memory or secure storage)
- Use HttpOnly cookies for refresh tokens
- Implement token rotation
- Clear tokens on logout
Rate Limiting
Authentication endpoints are rate limited:
- 10 requests per minute per IP for signup/signin
- 5 requests per minute per IP for password reset
- Prevents brute force attacks
๐ Admin Authentication (Legacy)
For backward compatibility, admin endpoints accept legacy JWT tokens.
Generating Admin Token
import jwt from 'jsonwebtoken';
const token = jwt.sign(
{ admin: true, userId: 'admin-id' },
process.env.ADMIN_TOKEN_SECRET,
{ expiresIn: '24h' }
);Using Admin Token
curl http://localhost:3001/api/get-feedback \
-H "Authorization: Bearer YOUR_ADMIN_TOKEN"๐งช Testing Authentication
Postman Collection
{
"info": {
"name": "Auth API Tests"
},
"item": [
{
"name": "Sign Up",
"request": {
"method": "POST",
"url": "{{base_url}}/api/auth/signup",
"body": {
"mode": "raw",
"raw": "{\n \"email\": \"test@example.com\",\n \"password\": \"test123\",\n \"name\": \"Test User\"\n}"
}
}
}
]
}Unit Test Example
describe('POST /api/auth/signup', () => {
it('creates a new user successfully', async () => {
const response = await request(app)
.post('/api/auth/signup')
.send({
email: 'test@example.com',
password: 'securepass123',
name: 'Test User',
});
expect(response.status).toBe(201);
expect(response.body.success).toBe(true);
expect(response.body.data.user.email).toBe('test@example.com');
expect(response.body.data.session.accessToken).toBeDefined();
});
});