diff --git a/backend/src/repositories/GroupRepository.js b/backend/src/repositories/GroupRepository.js index 7a22228..c7333d4 100644 --- a/backend/src/repositories/GroupRepository.js +++ b/backend/src/repositories/GroupRepository.js @@ -7,15 +7,16 @@ class GroupRepository { return await dbManager.transaction(async (db) => { // Füge Gruppe hinzu const groupResult = await db.run(` - INSERT INTO groups (group_id, year, title, description, name, upload_date) - VALUES (?, ?, ?, ?, ?, ?) + INSERT INTO groups (group_id, year, title, description, name, upload_date, approved) + VALUES (?, ?, ?, ?, ?, ?, ?) `, [ groupData.groupId, groupData.year, groupData.title, groupData.description || null, groupData.name || null, - groupData.uploadDate + groupData.uploadDate, + groupData.approved || false ]); // Füge Bilder hinzu diff --git a/backend/src/routes/batchUpload.js b/backend/src/routes/batchUpload.js index c8ee91c..39bdd43 100644 --- a/backend/src/routes/batchUpload.js +++ b/backend/src/routes/batchUpload.js @@ -1,9 +1,10 @@ const generateId = require("shortid"); const express = require('express'); const { Router } = require('express'); +const path = require('path'); const { endpoints } = require('../constants'); const UploadGroup = require('../models/uploadGroup'); -const GroupRepository = require('../repositories/GroupRepository'); +const groupRepository = require('../repositories/GroupRepository'); const dbManager = require('../database/DatabaseManager'); const ImagePreviewService = require('../services/ImagePreviewService'); @@ -97,7 +98,7 @@ router.post(endpoints.UPLOAD_BATCH, async (req, res) => { }); // Speichere Gruppe in SQLite - await GroupRepository.createGroup({ + await groupRepository.createGroup({ groupId: group.groupId, year: group.year, title: group.title, diff --git a/backend/src/routes/upload.js b/backend/src/routes/upload.js index c03ee24..18e5b59 100644 --- a/backend/src/routes/upload.js +++ b/backend/src/routes/upload.js @@ -4,6 +4,8 @@ const { Router } = require('express'); const { endpoints, UPLOAD_FS_DIR, PREVIEW_FS_DIR } = require('../constants'); const path = require('path'); const ImagePreviewService = require('../services/ImagePreviewService'); +const groupRepository = require('../repositories/GroupRepository'); +const fs = require('fs'); const router = Router(); @@ -20,6 +22,7 @@ router.post(endpoints.UPLOAD_FILE, async (req, res) => { } const file = req.files.file; + const groupName = req.body.groupName || 'Unnamed Group'; fileEnding = file.name.split(".") fileEnding = fileEnding[fileEnding.length - 1] @@ -36,6 +39,10 @@ router.post(endpoints.UPLOAD_FILE, async (req, res) => { }); }); + // Get file stats + const fileStats = fs.statSync(savePath); + const fileSize = fileStats.size; + // Generate preview asynchronously (don't wait for it) const previewFileName = ImagePreviewService._getPreviewFileName(fileName); const previewPath = ImagePreviewService.getPreviewPath(previewFileName); @@ -50,15 +57,45 @@ router.post(endpoints.UPLOAD_FILE, async (req, res) => { console.error(`Unexpected error during preview generation for ${fileName}:`, err); }); + // Create or update group in database + const groupId = generateId(); + const currentYear = new Date().getFullYear(); + const uploadDate = new Date().toISOString(); + + const groupData = { + groupId: groupId, + year: currentYear, + title: groupName, + description: `Einzelnes Bild Upload: ${file.name}`, + name: groupName, + uploadDate: uploadDate, + images: [{ + fileName: fileName, + originalName: file.name, + filePath: `${endpoints.UPLOAD_STATIC_DIRECTORY}/${fileName}`, + uploadOrder: 1, + fileSize: fileSize, + mimeType: file.mimetype, + previewPath: `${endpoints.PREVIEW_STATIC_DIRECTORY}/${previewFileName}` + }] + }; + + // Save to database + await groupRepository.createGroup(groupData); + + console.log(`✅ Group created: ${groupName} with image ${fileName}`); + // Return immediately with file path res.json({ filePath: `${endpoints.UPLOAD_STATIC_DIRECTORY}/${fileName}`, - fileName: fileName + fileName: fileName, + groupId: groupId, + groupName: groupName }); } catch(err) { - console.error(err); - return res.status(500).send(err); + console.error('Upload error:', err); + return res.status(500).json({ error: err.message }); } }); diff --git a/docker/dev/frontend/Dockerfile b/docker/dev/frontend/Dockerfile index d306915..cea0940 100644 --- a/docker/dev/frontend/Dockerfile +++ b/docker/dev/frontend/Dockerfile @@ -23,6 +23,9 @@ RUN chmod +x ./env.sh # Copy nginx configuration for development COPY docker/dev/frontend/nginx.conf /etc/nginx/conf.d/default.conf +# Copy htpasswd file for authentication +COPY docker/dev/frontend/config/htpasswd /etc/nginx/.htpasswd + # Make /app owned by the non-root user, then run npm as that user so # node_modules are created with the correct owner and we avoid an expensive # recursive chown later. diff --git a/docker/dev/frontend/config/htpasswd b/docker/dev/frontend/config/htpasswd new file mode 100644 index 0000000..34aef97 --- /dev/null +++ b/docker/dev/frontend/config/htpasswd @@ -0,0 +1 @@ +admin:$apr1$q2zv8h0V$ueMqnKIeQU6NN1YnHWNVe/ diff --git a/docker/dev/frontend/nginx.conf b/docker/dev/frontend/nginx.conf index 057d106..e8fa78c 100644 --- a/docker/dev/frontend/nginx.conf +++ b/docker/dev/frontend/nginx.conf @@ -1,121 +1,301 @@ -server { - listen 80; - server_name localhost; +events {server { + + worker_connections 1024; listen 80; + +} server_name localhost; + client_max_body_size 200M; - # API proxy to development backend - # Upload endpoint - location /api/upload { - proxy_pass http://backend-dev:5000/upload/; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; +http { + + include /etc/nginx/mime.types; # API proxy to development backend + + default_type application/octet-stream; # Upload endpoint + + location /api/upload { + + # Logging proxy_pass http://backend-dev:5000/upload/; + + log_format main '$remote_addr - $remote_user [$time_local] "$request" ' proxy_set_header Host $host; + + '$status $body_bytes_sent "$http_referer" ' proxy_set_header X-Real-IP $remote_addr; + + '"$http_user_agent" "$http_x_forwarded_for"'; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header X-Forwarded-Proto $scheme; + + access_log /var/log/nginx/access.log main; client_max_body_size 100M; + + error_log /var/log/nginx/error.log warn; } + + + + # Gzip Settings # Download original images + + gzip on; # Handle POST requests to upload endpoint + + gzip_vary on; location /api/upload { + + gzip_min_length 1024; proxy_pass http://backend-dev:5000/upload; + + gzip_proxied any; proxy_set_header Host $host; + + gzip_comp_level 6; proxy_set_header X-Real-IP $remote_addr; + + gzip_types proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + text/plain proxy_set_header X-Forwarded-Proto $scheme; + + text/css proxy_set_header Content-Type $content_type; + + text/xml client_max_body_size 100M; + + text/javascript } + + application/json + + application/javascript # Preview/thumbnail images (optimized for gallery views) + + application/xml+rss location /api/download { + + application/atom+xml proxy_pass http://backend-dev:5000/download; + + image/svg+xml; proxy_set_header Host $host; + + proxy_set_header X-Real-IP $remote_addr; + + # Server Config proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + server { proxy_set_header X-Forwarded-Proto $scheme; + + listen 80; } + + + + # Allow large uploads (50MB) location /api/previews { + + client_max_body_size 50M; proxy_pass http://backend-dev:5000/previews; + + proxy_set_header Host $host; + + # API proxy to backend-dev service proxy_set_header X-Real-IP $remote_addr; + + location /upload { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_pass http://backend-dev:5000; proxy_set_header X-Forwarded-Proto $scheme; + + proxy_set_header Host $host; } + + proxy_set_header X-Real-IP $remote_addr; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # Add groups endpoint + + proxy_set_header X-Forwarded-Proto $scheme; location /api/groups { + + proxy_pass http://backend-dev:5000/groups; + + # Allow large uploads for API too proxy_set_header Host $host; + + client_max_body_size 50M; 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; + + # API routes for new multi-upload features } + + location /api/upload { + + proxy_pass http://backend-dev:5000/upload; # Groups API + + proxy_set_header Host $host; location /api/groups { + + proxy_set_header X-Real-IP $remote_addr; proxy_pass http://backend-dev:5000/groups; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; + + proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + # Allow large uploads for batch upload proxy_set_header X-Forwarded-Proto $scheme; + + client_max_body_size 100M; } + + } + + # Moderation Groups API (PASSWORD PROTECTED) + + # API - Download original images location /moderation/groups { + + location /api/download { auth_basic "Restricted Area - Moderation API"; + + proxy_pass http://backend-dev:5000/download; auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_set_header Host $host; + + proxy_set_header X-Real-IP $remote_addr; proxy_pass http://backend-dev:5000/moderation/groups; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; + + proxy_set_header X-Forwarded-Proto $scheme; 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; - client_max_body_size 100M; - } - # Download original images - # Handle POST requests to upload endpoint - location /api/upload { - proxy_pass http://backend-dev:5000/upload; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # API - Preview/thumbnail images (optimized for gallery views) } + + location /api/previews { + + proxy_pass http://backend-dev:5000/previews; # Groups dynamic routes + + proxy_set_header Host $host; location ~ ^/groups/[a-zA-Z0-9_-]+(/.*)?$ { + + proxy_set_header X-Real-IP $remote_addr; proxy_pass http://backend-dev:5000; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; + + proxy_set_header X-Forwarded-Proto $scheme; 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_set_header Content-Type $content_type; - client_max_body_size 100M; - } - # Preview/thumbnail images (optimized for gallery views) - location /api/download { - proxy_pass http://backend-dev:5000/download; - 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; - } + # API - Groups (NO PASSWORD PROTECTION) } - location /api/previews { - proxy_pass http://backend-dev:5000/previews; - 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; - } + location /api/groups { - # Add groups endpoint - location /api/groups { - proxy_pass http://backend-dev:5000/groups; - 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_pass http://backend-dev:5000/groups; # Legacy download endpoint (backwards compatibility) - # Groups API - location /api/groups { - proxy_pass http://backend-dev:5000/groups; - 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_set_header Host $host; location /download { - # Moderation Groups API - location /moderation/groups { - proxy_pass http://backend-dev:5000/moderation/groups; - 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_set_header X-Real-IP $remote_addr; proxy_pass http://backend-dev:5000/download; - # Groups dynamic routes - location ~ ^/groups/[a-zA-Z0-9_-]+(/.*)?$ { - proxy_pass http://backend-dev:5000; - 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_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; - # Moderation routes - location /moderation { - proxy_pass http://backend-dev:5000; - 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_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; - # Legacy download endpoint (backwards compatibility) - location /download { - proxy_pass http://backend-dev:5000/download; - 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_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - # WebSocket support for hot reloading (React Dev Server) - location /ws { - proxy_pass http://127.0.0.1:3000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - 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; - # All other requests go to React Dev Server for Hot Module Reloading - location / { - proxy_pass http://127.0.0.1:3000; - proxy_http_version 1.1; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "Upgrade"; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + # Protected API - Moderation API routes (password protected) - must come before /groups } + + location /moderation/groups { + + auth_basic "Restricted Area - Moderation API"; # WebSocket support for hot reloading (React Dev Server) + + auth_basic_user_file /etc/nginx/.htpasswd; location /ws { + + proxy_pass http://127.0.0.1:3000; + + proxy_pass http://backend-dev:5000/moderation/groups; proxy_http_version 1.1; + + proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; + + proxy_set_header X-Real-IP $remote_addr; proxy_set_header Connection "Upgrade"; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $host; + + proxy_set_header X-Forwarded-Proto $scheme; proxy_set_header X-Real-IP $remote_addr; + + } proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + } + + # API - Groups API routes (NO PASSWORD PROTECTION) + + location ~ ^/groups/[a-zA-Z0-9_-]+(/.*)?$ { # Protected Frontend Routes - Moderation Pages (PASSWORD PROTECTED) + + proxy_pass http://backend-dev:5000; location /moderation { + + proxy_set_header Host $host; auth_basic "Restricted Area - Moderation"; + + proxy_set_header X-Real-IP $remote_addr; auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header X-Forwarded-Proto $scheme; proxy_pass http://127.0.0.1:3000; + + } proxy_http_version 1.1; + + proxy_set_header Upgrade $http_upgrade; + + location /download { proxy_set_header Connection "Upgrade"; + + proxy_pass http://backend-dev:5000; proxy_set_header Host $host; + + proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; + + proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; } + + proxy_set_header X-Forwarded-Proto $scheme; + + } # All other requests go to React Dev Server for Hot Module Reloading + + location / { + + # Frontend page - Groups overview (NO PASSWORD PROTECTION) - React Dev Server proxy_pass http://127.0.0.1:3000; + + location /groups { proxy_http_version 1.1; + + proxy_pass http://127.0.0.1:3000; proxy_set_header Upgrade $http_upgrade; + + proxy_http_version 1.1; proxy_set_header Connection "Upgrade"; + + proxy_set_header Upgrade $http_upgrade; proxy_set_header Host $host; + + proxy_set_header Connection "Upgrade"; proxy_set_header X-Real-IP $remote_addr; + + proxy_set_header Host $host; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + + proxy_set_header X-Real-IP $remote_addr; } + + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;} + } + + # Protected routes - Moderation (password protected) - React Dev Server + location /moderation { + auth_basic "Restricted Area - Moderation"; + auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # WebSocket support for hot reloading (React Dev Server) + location /ws { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # All other requests go to React Dev Server for Hot Module Reloading + location / { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + error_page 500 502 503 504 /50x.html; + location = /50x.html { + root /usr/share/nginx/html; + } } } \ No newline at end of file diff --git a/docker/dev/frontend/nginx.conf.backup b/docker/dev/frontend/nginx.conf.backup new file mode 100644 index 0000000..892fd25 --- /dev/null +++ b/docker/dev/frontend/nginx.conf.backup @@ -0,0 +1,129 @@ +server { + listen 80; + server_name localhost; + client_max_body_size 200M; + + # API proxy to development backend + # Upload endpoint + location /api/upload { + proxy_pass http://backend-dev:5000/upload/; + 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; + client_max_body_size 100M; + } + + # Download original images + # Handle POST requests to upload endpoint + location /api/upload { + proxy_pass http://backend-dev:5000/upload; + 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_set_header Content-Type $content_type; + client_max_body_size 100M; + } + + # Preview/thumbnail images (optimized for gallery views) + location /api/download { + proxy_pass http://backend-dev:5000/download; + 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; + } + + location /api/previews { + proxy_pass http://backend-dev:5000/previews; + 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; + } + + # Add groups endpoint + location /api/groups { + proxy_pass http://backend-dev:5000/groups; + 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; + } + + # Groups API + location /api/groups { + proxy_pass http://backend-dev:5000/groups; + 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; + } + + # Moderation Groups API (PASSWORD PROTECTED) + location /moderation/groups { + auth_basic "Restricted Area - Moderation API"; + auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_pass http://backend-dev:5000/moderation/groups; + 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; + } + + # Groups dynamic routes + location ~ ^/groups/[a-zA-Z0-9_-]+(/.*)?$ { + proxy_pass http://backend-dev:5000; + 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; + } + + # Legacy download endpoint (backwards compatibility) + location /download { + proxy_pass http://backend-dev:5000/download; + 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; + } + + # WebSocket support for hot reloading (React Dev Server) + location /ws { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # Protected Frontend Routes - Moderation Pages (PASSWORD PROTECTED) + location /moderation { + auth_basic "Restricted Area - Moderation"; + auth_basic_user_file /etc/nginx/.htpasswd; + + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } + + # All other requests go to React Dev Server for Hot Module Reloading + location / { + proxy_pass http://127.0.0.1:3000; + proxy_http_version 1.1; + proxy_set_header Upgrade $http_upgrade; + proxy_set_header Connection "Upgrade"; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; + } +} \ No newline at end of file