Files
scoffer/REGISTRATION_CONTROL.md

7.0 KiB

Registration Control Guide

Overview

The application now supports controlling user registration through an environment variable. This is a critical security feature that allows administrators to disable new user registrations in production environments while keeping existing user login functionality intact.

Environment Variable

Variable Default Description
ALLOW_REGISTRATION true Controls whether new user registration is allowed

Configuration

Enable Registration (Default)

ALLOW_REGISTRATION=true

or simply omit the variable (defaults to true)

Disable Registration

ALLOW_REGISTRATION=false

Usage Scenarios

Development Environment

Recommended: Enable registration for testing

# .env or .env.local
ALLOW_REGISTRATION=true

Production Environment

Recommended: Disable registration after initial setup

# .env.production
ALLOW_REGISTRATION=false

Staging Environment

Optional: Enable for testing, disable for demos

# .env.staging
ALLOW_REGISTRATION=true  # or false depending on needs

Implementation Details

Backend Behavior

When ALLOW_REGISTRATION=true (default):

  • POST /api/users/register accepts new registrations
  • Returns 201 with user data and JWT token on success
  • Returns 400 if user already exists

When ALLOW_REGISTRATION=false:

  • POST /api/users/register returns 403 Forbidden
  • Response: {"error": "Registration is currently disabled"}
  • Login functionality remains unaffected

Frontend Considerations

The frontend should handle the 403 response gracefully:

// Example error handling in registration form
try {
  const response = await api.post('/users/register', userData);
  // Handle success
} catch (error) {
  if (error.response?.status === 403) {
    // Registration disabled
    setError('Registration is currently disabled. Please contact an administrator.');
  } else {
    // Other errors (validation, user exists, etc.)
    setError(error.response?.data?.error || 'Registration failed');
  }
}

Deployment Examples

Quick Setup Commands

Enable registration:

echo "ALLOW_REGISTRATION=true" >> .env
docker-compose up -d --build

Disable registration:

echo "ALLOW_REGISTRATION=false" >> .env
docker-compose up -d --build

Toggle without rebuild (if container is already running):

# Update .env file
sed -i 's/ALLOW_REGISTRATION=.*/ALLOW_REGISTRATION=false/' .env

# Restart backend container to pick up new env var
docker-compose restart backend

Environment-Specific Deployments

Development with registration enabled:

# .env.dev
ALLOW_REGISTRATION=true
REACT_APP_API_URL=http://localhost:5000/api
JWT_SECRET=dev-secret-key

# Deploy
cp .env.dev .env
docker-compose up -d

Production with registration disabled:

# .env.prod
ALLOW_REGISTRATION=false
REACT_APP_API_URL=https://your-domain.com/api
JWT_SECRET=super-secure-production-key

# Deploy
cp .env.prod .env
docker-compose up -d --build

Security Best Practices

1. Disable Registration in Production

# Always set this in production
ALLOW_REGISTRATION=false

2. Create Initial Admin User

Before disabling registration, ensure you have at least one admin user:

# Method 1: Enable registration temporarily
ALLOW_REGISTRATION=true docker-compose up -d
# Register your admin user via frontend/API
# Then disable registration
ALLOW_REGISTRATION=false docker-compose restart backend

# Method 2: Create user directly in database (advanced)
docker-compose exec mongodb mongosh scoffer
# Use MongoDB commands to create user

3. Monitor Registration Attempts

Consider adding logging for blocked registration attempts:

// In backend/routes/users.js (optional enhancement)
if (!registrationEnabled) {
  console.log(`Registration attempt blocked from IP: ${req.ip}`);
  return res.status(403).json({ 
    error: 'Registration is currently disabled' 
  });
}

Troubleshooting

Registration Still Working After Disabling

Cause: Environment variable not picked up by container

Solutions:

  1. Restart the backend container:

    docker-compose restart backend
    
  2. Rebuild if env var was added after initial build:

    docker-compose up -d --build backend
    
  3. Verify environment variable in container:

    docker-compose exec backend env | grep ALLOW_REGISTRATION
    

Frontend Shows Registration Form When Disabled

Cause: Frontend doesn't know registration is disabled until API call

Solutions:

  1. Add API endpoint to check registration status:

    // GET /api/users/registration-status
    router.get('/registration-status', (req, res) => {
      res.json({ 
        enabled: process.env.ALLOW_REGISTRATION !== 'false' 
      });
    });
    
  2. Hide registration form based on API response

  3. Handle 403 error gracefully in registration form

Users Can't Login After Disabling Registration

Issue: This should NOT happen - login is separate from registration

Check:

  1. Verify ALLOW_REGISTRATION only affects /register endpoint
  2. Ensure /login endpoint is unaffected
  3. Check JWT_SECRET hasn't changed

API Reference

Registration Endpoint

Endpoint: POST /api/users/register

When Enabled (ALLOW_REGISTRATION=true):

curl -X POST http://localhost:5000/api/users/register \
  -H "Content-Type: application/json" \
  -d '{"username":"test","email":"test@example.com","password":"password123"}'

# Response: 201 Created
{
  "message": "User created successfully",
  "token": "jwt-token-here",
  "user": {
    "id": "user-id",
    "username": "test",
    "email": "test@example.com"
  }
}

When Disabled (ALLOW_REGISTRATION=false):

curl -X POST http://localhost:5000/api/users/register \
  -H "Content-Type: application/json" \
  -d '{"username":"test","email":"test@example.com","password":"password123"}'

# Response: 403 Forbidden
{
  "error": "Registration is currently disabled"
}

Login Endpoint (Unaffected)

Endpoint: POST /api/users/login

curl -X POST http://localhost:5000/api/users/login \
  -H "Content-Type: application/json" \
  -d '{"email":"existing@example.com","password":"password123"}'

# Response: 200 OK (regardless of ALLOW_REGISTRATION setting)
{
  "message": "Login successful",
  "token": "jwt-token-here",
  "user": {
    "id": "user-id",
    "username": "existing",
    "email": "existing@example.com"
  }
}

Quick Reference

Action Command
Enable registration ALLOW_REGISTRATION=true
Disable registration ALLOW_REGISTRATION=false
Check current setting docker-compose exec backend env | grep ALLOW_REGISTRATION
Restart backend docker-compose restart backend
Test registration curl -X POST localhost:5000/api/users/register -H "Content-Type: application/json" -d '{"username":"test","email":"test@test.com","password":"test123"}'