# 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) ```bash ALLOW_REGISTRATION=true ``` or simply omit the variable (defaults to `true`) ### Disable Registration ```bash ALLOW_REGISTRATION=false ``` ## Usage Scenarios ### Development Environment **Recommended**: Enable registration for testing ```bash # .env or .env.local ALLOW_REGISTRATION=true ``` ### Production Environment **Recommended**: Disable registration after initial setup ```bash # .env.production ALLOW_REGISTRATION=false ``` ### Staging Environment **Optional**: Enable for testing, disable for demos ```bash # .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: ```javascript // 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**: ```bash echo "ALLOW_REGISTRATION=true" >> .env docker-compose up -d --build ``` **Disable registration**: ```bash echo "ALLOW_REGISTRATION=false" >> .env docker-compose up -d --build ``` **Toggle without rebuild** (if container is already running): ```bash # 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**: ```bash # .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**: ```bash # .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 ```bash # Always set this in production ALLOW_REGISTRATION=false ``` ### 2. Create Initial Admin User Before disabling registration, ensure you have at least one admin user: ```bash # 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: ```javascript // 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: ```bash docker-compose restart backend ``` 2. Rebuild if env var was added after initial build: ```bash docker-compose up -d --build backend ``` 3. Verify environment variable in container: ```bash 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: ```javascript // 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`): ```bash 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`): ```bash 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` ```bash 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"}'` |