diff --git a/README.md b/README.md index 0b8d62a..b4b10b6 100644 --- a/README.md +++ b/README.md @@ -23,9 +23,13 @@ A powerful Django-based task management system with time tracking, tag organizat - **Formatted Display**: Time shown as H:MM:SS with visual indicators - **Running Timer Display**: Always visible timer in the UI when tracking time -### Collaboration +### Collaboration & User Management - **Task Sharing**: Share individual tasks or entire tags with other users - **Multi-user Support**: Full authentication and user management +- **Email Verification**: Secure email verification for new user registrations +- **Admin Approval**: Optional admin approval workflow for new users +- **User Profiles**: Customizable profiles with timezone and notification preferences +- **Password Management**: Secure password change functionality - **Shared Views**: See tasks shared with you alongside your own ### User Interface @@ -286,12 +290,32 @@ python manage.py loaddata data.json Key environment variables (see `.env.example`): -- `SECRET_KEY` - Django secret key (required in production) -- `DEBUG` - Enable debug mode (True/False) -- `ALLOWED_HOSTS` - Comma-separated list of allowed hosts +#### Core Settings +- `SECRET_KEY` - Django secret key (required in production, generate with `python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())"`) +- `DEBUG` - Enable debug mode (True/False, must be False in production) +- `ALLOWED_HOSTS` - Comma-separated list of allowed hosts (e.g., `tasks.firebugit.com,localhost`) +- `CSRF_TRUSTED_ORIGINS` - HTTPS origins for CSRF (e.g., `https://tasks.firebugit.com`) +- `SITE_DOMAIN` - Domain name for email links (e.g., `tasks.firebugit.com`) + +#### Database - `DATABASE_URL` - Database connection string (optional, overrides settings) -- `REDIS_URL` - Redis connection for Celery -- `CSRF_TRUSTED_ORIGINS` - HTTPS origins for CSRF + +#### Redis & Celery +- `REDIS_URL` - Redis connection for Celery (e.g., `redis://localhost:6379/0`) + +#### Email Configuration (Required for Email Verification) +- `EMAIL_BACKEND` - Email backend (use `django.core.mail.backends.smtp.EmailBackend` for production) +- `EMAIL_HOST` - SMTP server hostname (e.g., `smtp.gmail.com`, `smtp.sendgrid.net`) +- `EMAIL_PORT` - SMTP port (587 for TLS, 465 for SSL) +- `EMAIL_USE_TLS` - Use TLS (True/False, use True for port 587) +- `EMAIL_USE_SSL` - Use SSL (True/False, use True for port 465) +- `EMAIL_HOST_USER` - SMTP username/email +- `EMAIL_HOST_PASSWORD` - SMTP password or API key +- `DEFAULT_FROM_EMAIL` - From email address (e.g., `KeepItGoing `) +- `SERVER_EMAIL` - Server error email address + +#### Email Verification Settings +- `EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS` - Hours before verification tokens expire (default: 24) ## API Documentation @@ -426,45 +450,538 @@ python manage.py collectstatic ## Deployment -### Production Checklist +### Production Setup Guide -- [ ] Set `DEBUG = False` -- [ ] Configure strong `SECRET_KEY` -- [ ] Set up proper `ALLOWED_HOSTS` -- [ ] Configure `CSRF_TRUSTED_ORIGINS` for HTTPS -- [ ] Use PostgreSQL instead of SQLite -- [ ] Set up Redis for Celery -- [ ] Configure static file serving -- [ ] Set up SSL/TLS certificates -- [ ] Configure backup strategy -- [ ] Set up monitoring and logging +This guide covers deploying KeepItGoing Server in a production environment. -### Nginx Configuration +#### Prerequisites -Example nginx config for reverse proxy: +- Ubuntu/Debian Linux server (or similar) +- Root or sudo access +- Domain name pointing to your server +- SSL certificate (Let's Encrypt recommended) + +#### Step 1: System Preparation + +```bash +# Update system packages +sudo apt update && sudo apt upgrade -y + +# Install required system packages +sudo apt install -y python3.12 python3.12-venv python3-pip \ + postgresql postgresql-contrib nginx \ + redis-server git curl + +# Install Let's Encrypt certbot (optional, for SSL) +sudo apt install -y certbot python3-certbot-nginx +``` + +#### Step 2: Database Setup + +```bash +# Create PostgreSQL database and user +sudo -u postgres psql << EOF +CREATE DATABASE keepitgoing; +CREATE USER keepitgoing_user WITH PASSWORD 'STRONG_PASSWORD_HERE'; +ALTER ROLE keepitgoing_user SET client_encoding TO 'utf8'; +ALTER ROLE keepitgoing_user SET default_transaction_isolation TO 'read committed'; +ALTER ROLE keepitgoing_user SET timezone TO 'UTC'; +GRANT ALL PRIVILEGES ON DATABASE keepitgoing TO keepitgoing_user; +\q +EOF +``` + +#### Step 3: Application Setup + +```bash +# Create application user +sudo useradd -m -s /bin/bash keepitgoing +sudo su - keepitgoing + +# Clone repository +git clone https://git.firebugit.com/Firebug_IT/KeepItGoingServer.git +cd KeepItGoingServer + +# Create virtual environment +python3.12 -m venv venv +source venv/bin/activate + +# Install dependencies +pip install -r requirements.txt +pip install gunicorn psycopg2-binary + +# Create production environment file +cat > .env << 'EOF' +# Django Settings +SECRET_KEY=GENERATE_WITH_get_random_secret_key +DEBUG=False +ALLOWED_HOSTS=tasks.firebugit.com,localhost,127.0.0.1 +CSRF_TRUSTED_ORIGINS=https://tasks.firebugit.com +SITE_DOMAIN=tasks.firebugit.com + +# Database +DATABASE_URL=postgresql://keepitgoing_user:STRONG_PASSWORD_HERE@localhost:5432/keepitgoing + +# Email Configuration (Gmail example) +EMAIL_BACKEND=django.core.mail.backends.smtp.EmailBackend +EMAIL_HOST=smtp.gmail.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=your-email@gmail.com +EMAIL_HOST_PASSWORD=your-app-password +DEFAULT_FROM_EMAIL=KeepItGoing +SERVER_EMAIL=server@firebugit.com + +# Email Verification +EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS=24 + +# Redis (for Celery) +REDIS_URL=redis://localhost:6379/0 +EOF + +# Generate SECRET_KEY +python -c "from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())" +# Copy the output and replace SECRET_KEY in .env + +# Run migrations +export DJANGO_SETTINGS_MODULE=config.settings.production +python manage.py migrate + +# Create superuser (admin account) +python manage.py createsuperuser + +# Collect static files +python manage.py collectstatic --noinput + +# Exit back to root +exit +``` + +#### Step 4: Email Provider Setup + +Choose one of the following email providers: + +**Gmail:** +1. Enable 2-factor authentication on your Google account +2. Generate an App Password: https://myaccount.google.com/apppasswords +3. Use the app password in `EMAIL_HOST_PASSWORD` + +```env +EMAIL_HOST=smtp.gmail.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=your-email@gmail.com +EMAIL_HOST_PASSWORD=your-16-char-app-password +``` + +**SendGrid:** +1. Create SendGrid account and verify sender identity +2. Generate API key from Settings > API Keys +3. Configure: + +```env +EMAIL_HOST=smtp.sendgrid.net +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=apikey +EMAIL_HOST_PASSWORD=SG.your-api-key-here +``` + +**AWS SES:** +1. Verify domain in AWS SES console +2. Create SMTP credentials +3. Configure: + +```env +EMAIL_HOST=email-smtp.us-east-1.amazonaws.com +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=your-smtp-username +EMAIL_HOST_PASSWORD=your-smtp-password +``` + +**Mailgun:** +```env +EMAIL_HOST=smtp.mailgun.org +EMAIL_PORT=587 +EMAIL_USE_TLS=True +EMAIL_HOST_USER=postmaster@mg.yourdomain.com +EMAIL_HOST_PASSWORD=your-mailgun-password +``` + +#### Step 5: Gunicorn Service + +Create systemd service file for Gunicorn: + +```bash +sudo nano /etc/systemd/system/keepitgoing.service +``` + +Add the following content: + +```ini +[Unit] +Description=KeepItGoing Gunicorn daemon +After=network.target postgresql.service + +[Service] +Type=notify +User=keepitgoing +Group=keepitgoing +WorkingDirectory=/home/keepitgoing/KeepItGoingServer +Environment="PATH=/home/keepitgoing/KeepItGoingServer/venv/bin" +Environment="DJANGO_SETTINGS_MODULE=config.settings.production" +EnvironmentFile=/home/keepitgoing/KeepItGoingServer/.env +ExecStart=/home/keepitgoing/KeepItGoingServer/venv/bin/gunicorn \ + --workers 3 \ + --bind unix:/home/keepitgoing/KeepItGoingServer/gunicorn.sock \ + --timeout 60 \ + --access-logfile /var/log/keepitgoing/access.log \ + --error-logfile /var/log/keepitgoing/error.log \ + config.wsgi:application +ExecReload=/bin/kill -s HUP $MAINPID +KillMode=mixed +TimeoutStopSec=5 +PrivateTmp=true + +[Install] +WantedBy=multi-user.target +``` + +Create log directory: +```bash +sudo mkdir -p /var/log/keepitgoing +sudo chown keepitgoing:keepitgoing /var/log/keepitgoing +``` + +Enable and start service: +```bash +sudo systemctl daemon-reload +sudo systemctl enable keepitgoing +sudo systemctl start keepitgoing +sudo systemctl status keepitgoing +``` + +#### Step 6: Celery Service (Optional, for background tasks) + +```bash +sudo nano /etc/systemd/system/keepitgoing-celery.service +``` + +```ini +[Unit] +Description=KeepItGoing Celery Worker +After=network.target redis.service + +[Service] +Type=forking +User=keepitgoing +Group=keepitgoing +WorkingDirectory=/home/keepitgoing/KeepItGoingServer +Environment="PATH=/home/keepitgoing/KeepItGoingServer/venv/bin" +Environment="DJANGO_SETTINGS_MODULE=config.settings.production" +EnvironmentFile=/home/keepitgoing/KeepItGoingServer/.env +ExecStart=/home/keepitgoing/KeepItGoingServer/venv/bin/celery -A config worker -l info + +[Install] +WantedBy=multi-user.target +``` + +Enable and start: +```bash +sudo systemctl enable keepitgoing-celery +sudo systemctl start keepitgoing-celery +``` + +#### Step 7: Nginx Configuration + +```bash +sudo nano /etc/nginx/sites-available/keepitgoing +``` + +Add the following configuration: ```nginx +upstream keepitgoing { + server unix:/home/keepitgoing/KeepItGoingServer/gunicorn.sock fail_timeout=0; +} + server { - listen 443 ssl; + listen 80; server_name tasks.firebugit.com; - ssl_certificate /path/to/cert.pem; - ssl_certificate_key /path/to/key.pem; + # Redirect HTTP to HTTPS + return 301 https://$server_name$request_uri; +} +server { + listen 443 ssl http2; + server_name tasks.firebugit.com; + + # SSL Configuration + ssl_certificate /etc/letsencrypt/live/tasks.firebugit.com/fullchain.pem; + ssl_certificate_key /etc/letsencrypt/live/tasks.firebugit.com/privkey.pem; + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers HIGH:!aNULL:!MD5; + ssl_prefer_server_ciphers on; + + # Security Headers + add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always; + add_header X-Frame-Options "SAMEORIGIN" always; + add_header X-Content-Type-Options "nosniff" always; + add_header X-XSS-Protection "1; mode=block" always; + + client_max_body_size 10M; + + # Static files + location /static/ { + alias /home/keepitgoing/KeepItGoingServer/staticfiles/; + expires 30d; + add_header Cache-Control "public, immutable"; + } + + # Media files + location /media/ { + alias /home/keepitgoing/KeepItGoingServer/media/; + expires 7d; + } + + # Application location / { - proxy_pass http://localhost:8000; + proxy_pass http://keepitgoing; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; - } + proxy_redirect off; - location /static/ { - alias /path/to/static/; + # WebSocket support (if needed) + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "upgrade"; } } ``` +Enable site and restart nginx: +```bash +sudo ln -s /etc/nginx/sites-available/keepitgoing /etc/nginx/sites-enabled/ +sudo nginx -t +sudo systemctl restart nginx +``` + +#### Step 8: SSL Certificate (Let's Encrypt) + +```bash +# Obtain SSL certificate +sudo certbot --nginx -d tasks.firebugit.com + +# Certbot will automatically configure nginx +# Certificate auto-renews via cron +``` + +#### Step 9: Firewall Setup + +```bash +# Allow SSH, HTTP, and HTTPS +sudo ufw allow OpenSSH +sudo ufw allow 'Nginx Full' +sudo ufw enable +sudo ufw status +``` + +#### Step 10: Initial Admin User and Approval + +```bash +# Log in to the web interface at https://tasks.firebugit.com/admin +# Use the superuser credentials created in Step 3 + +# When new users register: +# 1. They receive verification email +# 2. After clicking verification link, you receive admin notification +# 3. Go to Admin > Users > select user(s) > Actions > "Approve selected users" +# 4. User receives approval email and can now log in +``` + +### Production Checklist + +Complete this checklist before going live: + +**Security:** +- [ ] Set `DEBUG = False` in production settings +- [ ] Generate and configure strong `SECRET_KEY` +- [ ] Set up proper `ALLOWED_HOSTS` (only your domain) +- [ ] Configure `CSRF_TRUSTED_ORIGINS` for HTTPS +- [ ] Install and configure SSL/TLS certificates +- [ ] Enable firewall (ufw) with only necessary ports +- [ ] Set strong passwords for database and admin users +- [ ] Review and harden SSH configuration +- [ ] Configure security headers in nginx + +**Database:** +- [ ] Use PostgreSQL (not SQLite) in production +- [ ] Configure regular database backups +- [ ] Set up database connection pooling if needed +- [ ] Verify database user has minimum required permissions + +**Email:** +- [ ] Configure production email backend (SMTP) +- [ ] Test email delivery (verification and approval emails) +- [ ] Verify sender domain/email is whitelisted +- [ ] Set up SPF, DKIM, and DMARC records for your domain +- [ ] Monitor email delivery rates and bounces + +**Application:** +- [ ] Run `python manage.py migrate` to apply all migrations +- [ ] Run `python manage.py collectstatic` for static files +- [ ] Create superuser account for admin access +- [ ] Test user registration and email verification flow +- [ ] Test admin approval workflow +- [ ] Configure `SITE_DOMAIN` to your production domain +- [ ] Set appropriate `EMAIL_VERIFICATION_TOKEN_EXPIRY_HOURS` + +**Services:** +- [ ] Set up Gunicorn systemd service +- [ ] Configure nginx as reverse proxy +- [ ] Set up Redis for Celery (if using background tasks) +- [ ] Configure Celery systemd service (if needed) +- [ ] Verify all services start on boot + +**Monitoring & Logging:** +- [ ] Set up application logging +- [ ] Configure nginx access and error logs +- [ ] Set up log rotation +- [ ] Configure system monitoring (disk, memory, CPU) +- [ ] Set up uptime monitoring +- [ ] Configure error alerting (email or Slack) +- [ ] Monitor database performance + +**Backups:** +- [ ] Configure automated database backups +- [ ] Set up media file backups +- [ ] Test backup restoration process +- [ ] Store backups off-site +- [ ] Document backup and recovery procedures + +**Performance:** +- [ ] Configure appropriate Gunicorn worker count +- [ ] Enable nginx gzip compression +- [ ] Set up static file caching +- [ ] Configure database connection pooling +- [ ] Monitor application performance +- [ ] Set up CDN for static files (optional) + +### Troubleshooting + +**Gunicorn won't start:** +```bash +# Check service status +sudo systemctl status keepitgoing + +# View logs +sudo journalctl -u keepitgoing -n 50 + +# Check if socket exists +ls -la /home/keepitgoing/KeepItGoingServer/gunicorn.sock +``` + +**Emails not sending:** +```bash +# Test email configuration in Django shell +sudo su - keepitgoing +cd KeepItGoingServer +source venv/bin/activate +export DJANGO_SETTINGS_MODULE=config.settings.production +python manage.py shell + +# In the shell: +from django.core.mail import send_mail +send_mail( + 'Test Subject', + 'Test message.', + 'noreply@firebugit.com', + ['your-email@example.com'], +) +# Check for any errors +``` + +**Static files not loading:** +```bash +# Recollect static files +sudo su - keepitgoing +cd KeepItGoingServer +source venv/bin/activate +export DJANGO_SETTINGS_MODULE=config.settings.production +python manage.py collectstatic --noinput + +# Check nginx configuration +sudo nginx -t + +# Check file permissions +ls -la /home/keepitgoing/KeepItGoingServer/staticfiles/ +``` + +**Database connection errors:** +```bash +# Test PostgreSQL connection +sudo -u postgres psql keepitgoing + +# Check if PostgreSQL is running +sudo systemctl status postgresql + +# Verify credentials in .env match database +``` + +**Permission denied errors:** +```bash +# Fix ownership +sudo chown -R keepitgoing:keepitgoing /home/keepitgoing/KeepItGoingServer + +# Fix socket permissions +sudo chown keepitgoing:www-data /home/keepitgoing/KeepItGoingServer/gunicorn.sock +``` + +### Maintenance Tasks + +**Update application:** +```bash +sudo su - keepitgoing +cd KeepItGoingServer +git pull origin main +source venv/bin/activate +pip install -r requirements.txt +export DJANGO_SETTINGS_MODULE=config.settings.production +python manage.py migrate +python manage.py collectstatic --noinput +exit + +# Restart services +sudo systemctl restart keepitgoing +``` + +**Database backup:** +```bash +# Manual backup +sudo -u postgres pg_dump keepitgoing > keepitgoing_backup_$(date +%Y%m%d).sql + +# Automated backup (add to crontab) +0 2 * * * sudo -u postgres pg_dump keepitgoing | gzip > /backups/keepitgoing_$(date +\%Y\%m\%d).sql.gz +``` + +**View application logs:** +```bash +# Gunicorn logs +sudo tail -f /var/log/keepitgoing/error.log +sudo tail -f /var/log/keepitgoing/access.log + +# Nginx logs +sudo tail -f /var/log/nginx/error.log +sudo tail -f /var/log/nginx/access.log + +# System logs +sudo journalctl -u keepitgoing -f +``` + ## Mobile App Integration This server works with the KeepItGoing Android app via the sync endpoint. @@ -496,6 +1013,16 @@ For issues and questions: ## Changelog +### Version 1.1.0 (2025-01-22) +- **Email Verification System**: Users must verify email before logging in +- **Admin Approval Workflow**: Admins approve new users via Django admin +- **Email Notifications**: Verification, approval, and admin notification emails +- **Password Change**: Users can change their password from profile page +- **Enhanced Registration**: Collect first name, last name, and timezone +- **Profile Enhancements**: Improved profile page with dark/light mode support +- **Security**: UUID tokens, expiration, one-time use, email enumeration protection +- **Custom Authentication**: Backend enforces verification and approval + ### Version 1.0.0 (2025-01-18) - Initial release - Complete task management system