Authentication API Overview
Authentication and Authorization System
This document describes the authentication and role-based access control (RBAC) system implemented in the Earthquake Catalogue Platform.
Overview
The platform uses NextAuth.js v4 with a custom credentials provider, JWT sessions, and MongoDB-backed user records. The system implements role-based access control with four distinct user roles.
User Roles
1. Admin
Full system access
User management (create, update, delete users, manage roles)
System settings and configuration
All catalogue operations (create, read, update, delete, export)
Import and merge operations
2. Editor
Create, upload, import, and merge catalogues
Update and delete catalogues
Export catalogues
Cannot manage users or system settings
3. Viewer
Read-only access to all catalogues
Export catalogues
Cannot create, modify, or delete catalogues
4. Guest
Limited read-only access to public/demo catalogues only
Cannot export or modify data
Setup and Installation
1. Environment Variables
Add the following to your .env file:
# NextAuth Configuration
NEXTAUTH_SECRET=<generate-with-openssl-rand-base64-32>
NEXTAUTH_URL=http://localhost:3000
# MongoDB Connection
MONGODB_URI=mongodb://localhost:27017
MONGODB_DATABASE=earthquake_catalogue
# Optional: Create default admin user during migration
CREATE_ADMIN_USER=true
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD=<generate-strong-temporary-password>
ADMIN_NAME=System Administrator
ADMIN_PASSWORD is required and must be at least 12 characters when CREATE_ADMIN_USER=true.
2. Run Database Migration
Execute the authentication schema migration to set up the database:
npm run migrate:auth
This will:
- Create the user_roles collection with role definitions
- Add indexes to the users collection for authentication fields
- Optionally create a default admin user (if CREATE_ADMIN_USER=true)
3. Change Default Admin Password
IMPORTANT: If you created a temporary admin user, change the password immediately after first login.
Current Auth Workflows
The current codebase includes these authentication workflows:
Registration at
/registercreates active users with theviewerrole.Login uses NextAuth credentials at
/login.Authenticated users can change their password at
/change-password.Password resets use
/forgot-passwordand/reset-password. Reset tokens expire after 1 hour and are stored hashed inpassword_reset_tokens.Users can request promotion to
editororadminfrom/profile.Admins review role requests at
/admin/role-requestsand manage users at/admin/users.
Password reset and role-request email notifications use EMAIL_WEBHOOK_URL when configured. If no webhook is configured, email delivery is logged rather than sent.
API Protection
Protected Endpoints
The following API endpoints are protected with role-based access control:
Editor+ Required (Editor or Admin)
POST /api/catalogues- Create cataloguePATCH /api/catalogues/[id]- Update catalogueDELETE /api/catalogues/[id]- Delete cataloguePOST /api/import/geonet- Import from GeoNetPOST /api/merge- Merge cataloguesPOST /api/upload- Upload catalogue files
Viewer+ Required (Viewer, Editor, or Admin)
GET /api/catalogues/[id]/export- Export catalogue
Admin Only
GET /api/users- List all usersGET /api/users/[id]- Get user detailsPATCH /api/users/[id]- Update user (role, status, etc.)DELETE /api/users/[id]- Delete userGET /api/role-requests- List role requestsPATCH /api/role-requests/[id]- Approve or reject role requests
Public Endpoints
GET /api/catalogues- List cataloguesGET /api/catalogues/[id]- Get catalogue detailsPOST /api/auth/register- User registrationPOST /api/auth/forgot-password- Request password resetPOST /api/auth/reset-password- Complete password resetPOST /api/auth/[...nextauth]- NextAuth endpoints
Frontend Usage
Authentication Hooks
import { useAuth, usePermission, useIsAdmin } from '@/lib/auth/hooks';
import { Permission } from '@/lib/auth/types';
function MyComponent() {
const { user, isAuthenticated, isLoading } = useAuth();
const canCreate = usePermission(Permission.CATALOGUE_CREATE);
const isAdmin = useIsAdmin();
if (isLoading) return <div>Loading...</div>;
if (!isAuthenticated) return <div>Please log in</div>;
return (
<div>
<p>Welcome, {user.name}!</p>
{canCreate && <button>Create Catalogue</button>}
{isAdmin && <button>Manage Users</button>}
</div>
);
}
Permission Gate Component
import { PermissionGate } from '@/components/auth/PermissionGate';
import { Permission, UserRole } from '@/lib/auth/types';
function MyPage() {
return (
<div>
<PermissionGate permission={Permission.CATALOGUE_CREATE}>
<button>Create Catalogue</button>
</PermissionGate>
<PermissionGate role={UserRole.ADMIN}>
<AdminPanel />
</PermissionGate>
<PermissionGate
anyRole={[UserRole.EDITOR, UserRole.ADMIN]}
fallback={<p>You need editor access</p>}
>
<EditorTools />
</PermissionGate>
</div>
);
}
Protected Routes
import { ProtectedRoute } from '@/components/auth/ProtectedRoute';
import { UserRole } from '@/lib/auth/types';
export default function AdminPage() {
return (
<ProtectedRoute role={UserRole.ADMIN}>
<AdminDashboard />
</ProtectedRoute>
);
}
Backend Usage
API Route Protection
import { NextRequest, NextResponse } from 'next/server';
import { requireEditor, requireAdmin } from '@/lib/auth/middleware';
export async function POST(request: NextRequest) {
// Require Editor role or higher
const authResult = await requireEditor(request);
if (authResult instanceof NextResponse) {
return authResult; // Returns 401 or 403 error
}
const { user } = authResult;
// Your protected logic here
return NextResponse.json({ success: true });
}
Available Middleware Functions
requireAuth(request)- Require any authenticated userrequirePermission(request, permission)- Require specific permissionrequireRole(request, role)- Require specific rolerequireAdmin(request)- Require Admin rolerequireEditor(request)- Require Editor or Admin rolerequireViewer(request)- Require Viewer, Editor, or Admin roleoptionalAuth(request)- Get session if available, don’t error if not
User Management
Admin User Management Page
Admins can manage users at /admin/users:
- View all users
- Change user roles
- Activate/deactivate users
- Delete users
Programmatic User Management
import { createUser, getUserByEmail, updateLastLogin } from '@/lib/auth/utils';
import { UserRole } from '@/lib/auth/types';
// Create a new user
const user = await createUser(
'user@example.com',
'password123',
'John Doe',
UserRole.VIEWER
);
// Get user by email
const existingUser = await getUserByEmail('user@example.com');
// Update last login
await updateLastLogin(user.id);
Security Best Practices
Always use HTTPS in production - Set
NEXTAUTH_URLto your HTTPS domainUse a strong secret - Generate
NEXTAUTH_SECRETwithopenssl rand -base64 32Change default passwords - Never use default admin credentials in production
Implement rate limiting - Already configured for API routes
Regular security audits - Review user permissions and access logs
Password requirements - Minimum 8 characters (enforced in registration)
Troubleshooting
“Authentication required” error
Ensure you’re logged in
Check that your session hasn’t expired (30 days by default)
Verify
NEXTAUTH_SECRETandNEXTAUTH_URLare set correctly
“Insufficient permissions” error
Check your user role in the profile page (
/profile)Contact an admin to upgrade your role if needed
Migration fails
Ensure MongoDB is running and accessible
Check
MONGODB_URIenvironment variableVerify database permissions
API Reference
See the ``API Documentation <./API.md>``_ for detailed endpoint specifications.