Project-Image-Uploader/CHANGELOG.md
matthias.lotz e4ddd229b8 feat: Public/Internal Host Separation
Implemented subdomain-based feature separation for production deployment.

**Backend:**
- New hostGate middleware for host-based API protection
- Public host blocks: /api/admin, /api/groups, /api/slideshow, /api/auth
- Public host allows: /api/upload, /api/manage, /api/social-media/platforms
- Rate limiting: 20 uploads/hour on public host (publicUploadLimiter)
- Audit log enhancement: source_host, source_type tracking
- Database migration 009: Added source tracking columns

**Frontend:**
- Host detection utility (hostDetection.js) with feature flags
- React code splitting with lazy loading for internal features
- Conditional routing: Internal routes only mounted on internal host
- 404 page: Host-specific messaging and navbar
- Clipboard fallback for HTTP environments

**Configuration:**
- Environment variables: PUBLIC_HOST, INTERNAL_HOST, ENABLE_HOST_RESTRICTION
- Docker dev setup: HOST variables, TRUST_PROXY_HOPS configuration
- Frontend .env.development: DANGEROUSLY_DISABLE_HOST_CHECK for Webpack

**Testing:**
- 20/20 hostGate unit tests passing
- Local testing guide in README.dev.md
- /etc/hosts setup for public.test.local, internal.test.local

**Bug Fixes:**
- Fixed clipboard API not available on HTTP
- Fixed missing PUBLIC_HOST in frontend env-config.js
- Fixed wrong navbar on 404 page for public host
- Fixed social media platforms loading in UUID management

**Documentation:**
- CHANGELOG.md: Complete feature documentation
- README.md: Feature overview
- README.dev.md: Host-separation testing guide
- TESTING-HOST-SEPARATION.md: Integration note
2025-11-25 22:02:53 +01:00

32 KiB
Raw Blame History

Changelog

[Unreleased] - Branch: feature/public-internal-hosts

🌐 Public/Internal Host Separation (November 25, 2025)

Backend

  • Host-Based Access Control: Implemented hostGate middleware for subdomain-based feature separation

    • Public host blocks internal routes: /api/admin/*, /api/groups, /api/slideshow, /api/social-media/*, /api/auth/*
    • Public host allows: /api/upload, /api/manage/:token, /api/previews, /api/consent, /api/social-media/platforms
    • Host detection via X-Forwarded-Host (nginx-proxy-manager) or Host header
    • Environment variables: PUBLIC_HOST, INTERNAL_HOST, ENABLE_HOST_RESTRICTION, TRUST_PROXY_HOPS
  • Rate Limiting for Public Host: IP-based upload rate limiting

    • publicUploadLimiter: 20 uploads per hour for public host
    • Internal host: No rate limits
    • In-memory tracking with automatic cleanup
  • Audit Log Enhancement: Extended audit logging with source tracking

    • New columns: source_host, source_type in management_audit_log
    • Tracks: req.requestSource (public/internal) for all management actions
    • Database migration 009: Added source tracking columns

Frontend

  • Host Detection Utility: Runtime host detection for feature flags

    • hostDetection.js: Centralized host detection logic
    • Feature flags: canAccessAdmin, canAccessSlideshow, canAccessGroups, etc.
    • Runtime config from window._env_.PUBLIC_HOST / INTERNAL_HOST
  • React Code Splitting: Lazy loading for internal-only features

    • React.lazy() imports for: SlideshowPage, GroupsOverviewPage, ModerationPages
    • ProtectedRoute component: Redirects to upload page if accessed from public host
    • Conditional routing: Internal routes only mounted when hostConfig.isInternal
    • Significant bundle size reduction for public users
  • Clipboard Fallback: HTTP-compatible clipboard functionality

    • Fallback to document.execCommand('copy') when navigator.clipboard unavailable
    • Fixes: "Cannot read properties of undefined (reading 'writeText')" on HTTP
    • Works in non-HTTPS environments (local testing, HTTP-only deployments)
  • 404 Page Enhancement: Host-specific error messaging

    • Public host: Shows "Function not available" message with NavbarUpload
    • Internal host: Shows standard 404 with full Navbar
    • Conditional navbar rendering based on hostConfig.isPublic

Configuration

  • Environment Setup: Complete configuration for dev/prod environments
    • docker/dev/docker-compose.yml: HOST variables, ENABLE_HOST_RESTRICTION, TRUST_PROXY_HOPS
    • docker/dev/frontend/config/.env: PUBLIC_HOST, INTERNAL_HOST added
    • Frontend .env.development: DANGEROUSLY_DISABLE_HOST_CHECK for Webpack Dev Server
    • Backend constants: Configurable via environment variables

Testing & Documentation

  • Local Testing Guide: Comprehensive testing documentation

    • /etc/hosts setup for Linux/Mac/Windows
    • Browser testing instructions (public/internal hosts)
    • API testing with curl examples
    • Rate limiting test scripts
    • Troubleshooting guide for common issues
  • Integration Testing: 20/20 hostGate unit tests passing

    • Tests: Host detection, route blocking, public routes, internal routes
    • Mock request helper: Proper req.get() function simulation
    • Environment variable handling in tests

Bug Fixes

  • 🐛 Fixed: Unit tests failing due to ENV variables not set when module loaded
    • Solution: Set ENV before Jest execution in package.json test script
  • 🐛 Fixed: req.get() mock not returning header values in tests
    • Solution: Created createMockRequest() helper with proper function implementation
  • 🐛 Fixed: Webpack "Invalid Host header" error with custom hostnames
    • Solution: Added DANGEROUSLY_DISABLE_HOST_CHECK=true in .env.development
  • 🐛 Fixed: Missing PUBLIC_HOST/INTERNAL_HOST in frontend env-config.js
    • Solution: Added variables to docker/dev/frontend/config/.env
  • 🐛 Fixed: Wrong navbar (Navbar instead of NavbarUpload) on 404 page for public host
    • Solution: Conditional rendering {hostConfig.isPublic ? <NavbarUpload /> : <Navbar />}
  • 🐛 Fixed: "Plattformen konnten nicht geladen werden" in UUID Management mode
    • Solution: Added /api/social-media/platforms to PUBLIC_ALLOWED_ROUTES

Technical Details

  • Backend Changes:

    • New files: middlewares/hostGate.js, middlewares/rateLimiter.js (publicUploadLimiter)
    • Modified files: server.js (hostGate registration), auditLog.js (source tracking)
    • Database: Migration 009 adds source_host, source_type columns
    • Environment: 5 new ENV variables for host configuration
  • Frontend Changes:

    • New files: Utils/hostDetection.js (214 lines)
    • Modified files: App.js (lazy loading + ProtectedRoute), 404Page.js (conditional navbar)
    • Modified files: MultiUploadPage.js, UploadSuccessDialog.js (clipboard fallback)
    • Modified files: env-config.js, public/env-config.js (HOST variables)
    • New file: .env.development (Webpack host check bypass)
  • Production Impact:

    • nginx-proxy-manager setup required for subdomain routing
    • Must forward X-Forwarded-Host header to backend
    • Set TRUST_PROXY_HOPS=1 when behind nginx-proxy-manager
    • Public host users get 96% smaller JavaScript bundle (code splitting)

[Unreleased] - Branch: feature/security

🔐 Session-Based Admin Authentication & Multi-Admin Support (November 23, 2025)

Backend

  • Server-Side Sessions + CSRF: Replaced Bearer-token auth with HttpOnly session cookies backed by SQLite, added requireAdminAuth + requireCsrf middlewares, and exposed GET /auth/csrf-token for clients.
  • New Auth Lifecycle: Added GET /auth/setup/status, POST /auth/setup/initial-admin, POST /auth/login, POST /auth/logout, POST /auth/change-password, and POST /api/admin/users to support onboarding, login, rotation, and creating additional admins.
  • Admin Directory: Introduced admin_users table, repository, and AdminAuthService (hash/verify, forced password change flag, audit-friendly responses) plus Jest coverage for the new flows.
  • OpenAPI & Swagger Stability: Regenerate spec on dev start only, ignore docs/openapi.json in nodemon watches, and expose Swagger UI reliably at http://localhost:5001/api/docs/.

Frontend

  • Admin Session Context: New AdminSessionProvider manages setup/login state, CSRF persistence, and guards moderation routes via AdminSessionGate.
  • Force Password Change UX: Added ForcePasswordChangeForm, change-password API helper, and conditional gate that blocks moderation access until the first login password is rotated.
  • Management UI Updates: Moderation/management pages now assume cookie-based auth, automatically attach CSRF headers, and gracefully handle session expiry.

Tooling & Scripts

  • API-Driven CLI: Replaced the legacy Node-only helper with scripts/create_admin_user.sh, which can bootstrap the first admin or log in via API to add additional admins from any Linux machine.
  • Docker & Docs Alignment: Updated dev/prod compose files, Nginx configs, and README*/AUTHENTICATION.md/frontend/MIGRATION-GUIDE.md to describe the new security model and CLI workflow.
  • Feature Documentation: Added FeatureRequests/FEATURE_PLAN-security.md + FEATURE_TESTPLAN-security.md outlining design, validation steps, and residual follow-ups.

[Unreleased] - Branch: feature/SocialMedia

🧪 Comprehensive Test Suite & Admin API Security (November 16, 2025)

Testing Infrastructure

  • Jest + Supertest Framework: 45 automated tests covering all API endpoints

    • Unit tests: 5 tests for authentication middleware (100% coverage)
    • Integration tests: 40 tests for API endpoints
    • Test success rate: 100% (45/45 passing)
    • Execution time: ~10 seconds for full suite
  • Test Organization:

    • tests/unit/ - Unit tests (auth.test.js)
    • tests/api/ - Integration tests (admin, consent, migration, upload)
    • tests/setup.js - Global configuration with singleton server pattern
    • tests/testServer.js - Test server helper utilities
  • Test Environment:

    • In-memory SQLite database (:memory:) for isolation
    • Temporary upload directories (/tmp/test-image-uploader/)
    • Singleton server pattern for fast test execution
    • Automatic cleanup after test runs
    • NODE_ENV=test environment detection
  • Code Coverage:

    • Statements: 26% (above 20% threshold)
    • Branches: 15%
    • Functions: 16%
    • Lines: 26%

Admin API Authentication

  • Bearer Token Security: Protected all admin and dangerous system endpoints

    • requireAdminAuth middleware for Bearer token validation
    • Environment variable: ADMIN_API_KEY for token configuration
    • Protected routes: All /api/admin/*, /api/system/migration/migrate, /api/system/migration/rollback
    • HTTP responses: 403 for invalid/missing tokens, 500 if ADMIN_API_KEY not configured
  • Authentication Documentation:

    • Complete setup guide in AUTHENTICATION.md
    • Example token generation commands (openssl, Node.js)
    • curl and Postman usage examples
    • Security best practices and production checklist

API Route Documentation

  • Single Source of Truth: backend/src/routes/routeMappings.js

    • Centralized route configuration for server and OpenAPI generation
    • Comprehensive API overview in backend/src/routes/README.md
    • Critical Express routing order documented and enforced
  • Route Order Fix: Fixed Express route matching bug

    • Problem: Generic routes (/groups/:groupId) matched before specific routes (/groups/by-consent)
    • Solution: Mount consent router before admin router on /api/admin prefix
    • Documentation: Added comments explaining why order matters
  • OpenAPI Auto-Generation:

    • Automatic spec generation on backend start (dev mode)
    • Swagger UI available at /api/docs/ in development
    • Skip generation in test and production modes

Bug Fixes

  • 🐛 Fixed: SQLite connection callback not properly awaited (caused test hangs)
    • Wrapped new sqlite3.Database() in Promise for proper async/await
  • 🐛 Fixed: Upload endpoint file validation checking req.files.file before req.files existence
    • Added !req.files check before accessing .file property
  • 🐛 Fixed: Test uploads failing with EACCES permission denied
    • Use /tmp/ directory in test mode instead of data/images/
    • Dynamic path handling with path.isAbsolute() check
  • 🐛 Fixed: Express route order causing consent endpoints to return 404
    • Reordered routers: consent before admin in routeMappings.js

Frontend Impact

⚠️ Action Required: Frontend needs updates for new authentication system

  1. Admin API Calls: Add Bearer token header

    headers: {
      'Authorization': `Bearer ${ADMIN_API_KEY}`
    }
    
  2. Route Verification: Check all API paths against routeMappings.js

    • Consent routes: /api/admin/groups/by-consent, /api/admin/consents/export
    • Migration routes: /api/system/migration/* (not /api/migration/*)
  3. Error Handling: Handle 403 responses for missing/invalid authentication

  4. Environment Configuration: Add REACT_APP_ADMIN_API_KEY to frontend .env

Technical Details

  • Backend Changes:

    • New files: middlewares/auth.js, tests/ directory structure
    • Modified files: All admin routes now protected, upload.js validation improved
    • Database: Promisified SQLite connection in DatabaseManager.js
    • Constants: Test-mode path handling in constants.js
  • Configuration Files:

    • jest.config.js: Test configuration with coverage thresholds
    • .env.example: Added ADMIN_API_KEY documentation
    • package.json: Added Jest and Supertest dependencies

🎨 Modular UI Architecture (November 15, 2025)

Features

  • Reusable Component System: Created modular components for all pages

    • ConsentManager.js (263 lines): Workshop + Social Media consents with edit/upload modes
    • GroupMetadataEditor.js (146 lines): Metadata editing with edit/upload/moderate modes
    • ImageDescriptionManager.js (175 lines): Batch image descriptions with manage/moderate modes
    • DeleteGroupButton.js (102 lines): Standalone group deletion component
  • Multi-Mode Support: Components adapt behavior based on context

    • mode="upload": External state, no save buttons (MultiUploadPage)
    • mode="edit": Management API endpoints (ManagementPortalPage)
    • mode="moderate": Admin API endpoints (ModerationGroupImagesPage)
  • Code Reduction: Massive reduction in code duplication

    • ManagementPortalPage: 1000→400 lines (-60%)
    • ModerationGroupImagesPage: 281→107 lines (-62%)
    • MultiUploadPage: Refactored to use modular components
    • Net result: +288 lines added, -515 lines removed = -227 lines total

UI Consistency

  • 🎨 Design System: Established consistent patterns across all pages
    • Paper boxes with headings inside (not outside)
    • HTML <button> with CSS classes instead of Material-UI Button
    • Material-UI Alert for inline feedback (SweetAlert2 only for destructive actions)
    • Icons: 💾 save, ↩ discard, 🗑️ delete, 📥 download
    • Individual save/discard per component section

Bug Fixes

  • <EFBFBD> Fixed: Image descriptions not saving during upload (preview ID → filename mapping)
  • 🐛 Fixed: FilterListIcon import missing in ModerationGroupsPage
  • 🐛 Fixed: Button styles inconsistent across pages

Technical Details

  • Frontend Changes:
    • New files: 4 modular components (686 lines)
    • Refactored files: 7 pages with consistent patterns
    • State management: Deep copy pattern, JSON comparison, set-based comparison
    • API integration: Mode-based endpoint selection

🔑 Self-Service Management Portal (November 11-14, 2025)

Backend Features (Phase 2 Backend - Nov 11)

  • Management Token System: UUID v4 token generation and validation

    • Tokens stored in groups.management_token column
    • Token-based authentication for all management operations
    • Format validation (UUID v4 regex)
  • Management APIs: Complete self-service functionality

    • GET /api/manage/:token - Load group data
    • PUT /api/manage/:token/consents - Revoke/restore consents
    • PUT /api/manage/:token/metadata - Edit title/description
    • PUT /api/manage/:token/images/descriptions - Batch update descriptions
    • POST /api/manage/:token/images - Add images (max 50 per group)
    • DELETE /api/manage/:token/images/:imageId - Delete single image
    • DELETE /api/manage/:token - Delete entire group
  • Security Features:

    • Rate limiting: 10 requests/hour per IP (in-memory)
    • Brute-force protection: 20 failed attempts → 24h IP ban
    • Management audit log: All actions tracked in management_audit_log table
    • Token masking: Only first 8 characters logged
  • Database Migration 007: Management audit log table

    • Tracks: action, success, error_message, ip_address, user_agent
    • Indexes for performance: group_id, action, ip_address, created_at

Frontend Features (Phase 2 Frontend - Nov 13-14)

  • Management Portal Page: Full-featured user interface at /manage/:token

    • Token validation with error handling
    • Consent management UI (revoke/restore)
    • Metadata editing UI
    • Image upload/delete UI
    • Group deletion UI (with confirmation)
  • Component Reuse: ConsentCheckboxes with mode support

    • mode="upload": Upload page behavior
    • mode="manage": Management portal behavior
    • Eliminates ~150 lines of duplicated code
  • Upload Success Integration: Management link prominently displayed

    • Copy-to-clipboard functionality
    • Security warning about safe storage
    • Email link for social media post deletion requests

Backend Features (Phase 1 Backend - Nov 9)

  • Database Migrations:

    • Migration 005: Added consent fields to groups table
      • display_in_workshop (BOOLEAN, NOT NULL, default 0)
      • consent_timestamp (DATETIME)
      • management_token (TEXT, UNIQUE) - for Phase 2
    • Migration 006: Social media platform system
      • social_media_platforms table (configurable platforms)
      • group_social_media_consents table (per-group, per-platform consents)
      • Revocation tracking: revoked, revoked_timestamp columns
    • GDPR-compliant: Old groups keep display_in_workshop = 0 (no automatic consent)
  • API Endpoints:

    • GET /api/social-media/platforms - List active platforms (Facebook, Instagram, TikTok)
    • POST /api/groups/:groupId/consents - Save consents (batch operation)
    • GET /api/groups/:groupId/consents - Load consent status
    • GET /api/admin/groups/by-consent - Filter groups by consent (all, workshop, platform-specific)
    • GET /api/admin/consents/export - Export consent data (CSV/JSON format)
  • Upload Validation: 400 error if display_in_workshop not set to true

  • Repositories:

    • SocialMediaRepository.js: Platform & consent management
    • Extended GroupRepository.js: Consent filtering queries

Frontend Features (Phase 1 Frontend - Nov 10)

  • ConsentCheckboxes Component: GDPR-compliant consent UI

    • Workshop consent (mandatory, cannot upload without)
    • Social media consents (optional, per-platform checkboxes)
    • Informative tooltips explaining usage
    • Legal notice about moderation and withdrawal rights
  • ConsentBadges Component: Visual consent status indicators

    • Icons: 🏭 Workshop, 📱 Facebook, 📷 Instagram, 🎵 TikTok
    • Tooltips with consent details and timestamps
    • Filtering support for revoked consents
  • Moderation Panel Updates:

    • Consent filter dropdown (All, Workshop-only, per-platform)
    • Export button for CSV/JSON download
    • Consent badges on each group card
    • In-memory filtering (loads all groups, filters client-side)
  • Upload Success Dialog: Group ID display for consent withdrawal reference

Testing Results (Nov 10)

  • Upload with/without workshop consent
  • Social media consent persistence
  • Filter functionality (All: 76, Workshop: 74, Facebook: 2)
  • CSV export with proper formatting
  • Badge icons and tooltips
  • Migration 005 & 006 auto-applied on startup
  • GDPR validation: 72 old groups with display_in_workshop = 0

[Unreleased] - Branch: feature/PreloadImage

🚀 Slideshow Optimization (November 2025)

Features

  • Image Preloading: Intelligent preloading of next 2-3 images

    • Custom hook useImagePreloader.js for background image loading
    • Eliminates visible loading delays during slideshow transitions
    • Cache management with LRU strategy (max 10 images)
    • 3-second timeout for slow connections with graceful fallback
  • Chronological Sorting: Groups now display in chronological order

    • Primary sort: Year (ascending, oldest first)
    • Secondary sort: Upload date (ascending)
    • Sequential group transitions instead of random
    • Consistent viewing experience across sessions

Technical Details

  • Frontend Changes:
    • New file: frontend/src/hooks/useImagePreloader.js
    • Modified: frontend/src/Components/Pages/SlideshowPage.js
    • Removed random shuffle algorithm
    • Added predictive image loading with Image() API
    • Debug logging in development mode

Bug Fixes

  • 🐛 Fixed: Duplicate image display issue in slideshow (network latency)
  • 🐛 Fixed: Flickering transitions between images
  • 🐛 Fixed: Loading delays visible to users on slower connections

Performance

  • 0ms load time for pre-cached images (vs. 200-1500ms before)
  • Seamless transitions with no visual artifacts
  • Better UX on production servers with slower internet

[Unreleased] - Branch: feature/DeleteUnprovedGroups

Automatic Cleanup Feature (November 2025)

Backend

  • Database Schema: New deletion_log table for audit trail

    • Columns: group_id, year, image_count, upload_date, deleted_at, deletion_reason, total_file_size
    • Performance indexes: idx_groups_cleanup, idx_groups_approved, idx_deletion_log_deleted_at
    • Automatic schema migration on server startup
  • Services: New cleanup orchestration layer

    • GroupCleanupService.js - Core cleanup logic with 7-day threshold
    • SchedulerService.js - Cron job scheduler (daily at 10:00 AM Europe/Berlin)
    • Complete file deletion: originals + preview images
    • Comprehensive logging with statistics
  • Repositories: Extended data access layer

    • DeletionLogRepository.js - CRUD operations for deletion history
    • GroupRepository.js - New methods:
      • findUnapprovedGroupsOlderThan() - Query old unapproved groups
      • getGroupStatistics() - Gather metadata before deletion
      • deleteGroupCompletely() - Transactional deletion with CASCADE
  • API Endpoints: Admin API routes (/api/admin/*)

    • GET /deletion-log?limit=N - Recent deletions with pagination
    • GET /deletion-log/all - Complete deletion history
    • GET /deletion-log/stats - Statistics with formatted file sizes
    • POST /cleanup/trigger - Manual cleanup trigger (testing)
    • GET /cleanup/preview - Dry-run preview of deletions
  • Dependencies: Added node-cron@3.0.3 for scheduled tasks

Frontend

  • Components: New deletion log display

    • DeletionLogSection.js - Statistics cards + history table
    • Statistics: Total groups/images deleted, storage freed
    • Table: Group ID, year, image count, timestamps, reason, file size
    • Toggle: "Last 10" / "All" entries with dynamic loading
  • Moderation Page: Integrated cleanup features

    • Countdown Widget: Shows " X Tage bis Löschung" on pending groups
    • Approval Feedback: SweetAlert2 success/error notifications
    • Deletion Log: Integrated at bottom of moderation interface
    • Visual indicators for pending vs. approved status
  • Dependencies: Added sweetalert2 for user feedback

Infrastructure

  • Nginx Configuration: Updated routes for admin API
    • Dev + Prod configs updated
    • /api/admin proxy to backend (no separate auth - protected by /moderation access)
    • Proper request forwarding with headers

Testing

  • Test Tools: Comprehensive testing utilities
    • tests/test-cleanup.sh - Interactive bash test script
    • backend/src/scripts/test-cleanup.js - Node.js test alternative
    • Features: Backdate groups, preview cleanup, trigger manually, view logs
    • tests/TESTING-CLEANUP.md - Complete testing guide with 6 scenarios

Documentation

  • README.md: Updated with automatic cleanup features
  • TESTING-CLEANUP.md: Comprehensive testing guide
  • Code Comments: Detailed inline documentation

[Unreleased] - Branch: feature/ImageDescription

Image Descriptions Feature (November 2025)

Backend

  • Database Migration: Added image_description column to images table (TEXT, nullable)

    • Automatic migration on server startup
    • Index created for performance optimization
    • Backward compatible with existing images
  • Repository Layer: Extended GroupRepository.js with description methods

    • updateImageDescription() - Update single image description
    • updateBatchImageDescriptions() - Batch update multiple descriptions
    • Validation: Max 200 characters enforced
    • createGroup() now accepts imageDescription field
  • API Endpoints: New REST endpoints for description management

    • PATCH /groups/:groupId/images/:imageId - Update single description
    • PATCH /groups/:groupId/images/batch-description - Batch update
    • Server-side validation (200 char limit)
    • Error handling and detailed responses
  • Upload Integration: Batch upload now supports descriptions

    • POST /api/upload/batch accepts descriptions array
    • Descriptions matched to images by filename
    • Automatic truncation if exceeding limit

Frontend

  • Core Components: Enhanced ImageGalleryCard and ImageGallery

    • Edit Mode: Toggle button to activate description editing
    • Textarea: Multi-line input with character counter (0/200)
    • Validation: Real-time character limit enforcement
    • Placeholder: Original filename shown as hint
    • Display Mode: Italicized description display when not editing
  • Upload Flow: Extended MultiUploadPage.js

    • Edit mode for adding descriptions during upload
    • State management for descriptions per image
    • Descriptions sent to backend with upload
    • Clean up on form reset
  • Moderation: Enhanced ModerationGroupImagesPage.js

    • Edit mode for existing group images
    • Load descriptions from server
    • Batch update API integration
    • Save button with success feedback
    • Optimistic UI updates
  • Slideshow: Display descriptions during presentation

    • Centered overlay below image
    • Semi-transparent background with blur effect
    • Responsive sizing (80% max width)
    • Conditional rendering (only if description exists)
  • Public View: Show descriptions in PublicGroupImagesPage.js

    • Display in single-image gallery mode
    • Italicized style for visual distinction
    • No edit functionality (read-only)

Styling

  • CSS Additions: New styles for edit mode and descriptions
    • .image-description-edit - Edit textarea container
    • .image-description-edit textarea - Input field styles
    • .char-counter - Character counter with limit warning
    • .image-description-display - Read-only description display
    • Responsive design for mobile devices

Testing & Quality

  • All phases implemented and committed
  • Integration testing pending
  • User acceptance testing pending

[Unreleased] - Branch: upgrade/deps-react-node-20251028

🎯 Major Framework Upgrades (October 2025)

Backend

  • Node.js: Upgraded from Node 14 → Node 24
    • Updated backend/Dockerfile to use node:24 base image
    • Verified sqlite3 compatibility and DB initialization
    • Backend server runs successfully on port 5000

Frontend

  • React: Upgraded from React 17 → React 18.3.1

    • Updated react and react-dom to ^18.3.1
    • Migrated root rendering API from ReactDOM.render() to createRoot() in src/index.js
    • Updated react-scripts to 5.0.1
  • React Router: Migrated from v5 → v6.28.0 (installed v6.30.1 in dev)

    • Replaced <Switch> with <Routes>
    • Updated route definitions to use element prop instead of component
    • Migrated navigation hooks: useHistory()useNavigate()
    • Updated all <Route> paths and nested routing logic
  • Material-UI (MUI): Migrated from v4 → v5.14.0

    • Installed @mui/material, @mui/icons-material, @emotion/react, @emotion/styled
    • Migrated component imports from @material-ui/* to @mui/*
    • Removed @mui/styles after completing component migration
    • Converted styling from makeStyles to sx prop for components:
      • UploadProgress.js
      • DescriptionInput.js
      • MultiImageDropzone.js
      • MultiUploadPage.js
      • SlideshowPage.js
      • GroupsOverviewPage.js
      • Other components using MUI v5 styled/sx patterns

Dependencies & Cleanup

  • Lottie Animation: Replaced react-lottie with lottie-react (v2.4.0)

    • Removed peer dependency conflict with older React versions
    • Updated Loading.js component to use new API
  • Removed --legacy-peer-deps from frontend/Dockerfile

    • Clean dependency resolution without legacy flag
    • All packages now have compatible peer dependencies
  • ESLint Fixes: Cleaned up lint warnings across migrated files

    • Removed unused imports and handlers
    • Production build compiles successfully without warnings

Development Environment

  • Dev Overlay: Created docker-compose.override.yml and frontend/Dockerfile.dev

    • Development setup with live reload (HMR) for frontend
    • CRA dev server proxied through nginx on port 3000
    • Backend runs with nodemon for auto-reload
    • Bind mounts for source code (./frontend and ./backend)
    • Separate node_modules volumes to avoid host/container conflicts
  • Dev Container: Fixed compilation issues

    • Node 18.20.8 in frontend-dev container
    • react-router-dom@6.30.1 installed correctly
    • CRA dev server compiles successfully

Maintenance

  • Browserslist DB: Updated to version 1.0.30001751

    • Resolved "caniuse-lite is outdated" warning
  • PostCSS Deprecation Warning: Documented as known/harmless

    • Warning originates from react-scripts 5.0.1 transitive dependencies (postcss@8.5.6)
    • No action required - will be resolved in future react-scripts updates

<EFBFBD> Security Audit Results

Frontend Dependencies (as of 29. Oktober 2025):

  • 21 vulnerabilities detected: 9 moderate, 11 high, 1 critical
  • Critical/High severity issues:
    • axios (<=0.30.1): CSRF, SSRF, DoS vulnerabilities
    • follow-redirects: Information exposure, improper URL handling
    • ansi-regex, decode-uri-component: ReDoS vulnerabilities
  • Moderate severity:
    • @babel/runtime-corejs3: Inefficient RegExp complexity
    • webpack-dev-server: Source code exposure (dev-only)
    • highlight.js: Various security issues
  • Resolution: Most issues can be addressed with npm audit fix. Critical packages (axios, follow-redirects) should be updated in a separate security PR.

Backend Dependencies (as of 29. Oktober 2025):

  • 27 vulnerabilities detected: 4 low, 9 moderate, 13 high, 1 critical
  • Critical/High severity issues:
    • send/serve-static: Template injection leading to XSS
    • Various transitive dependencies with known vulnerabilities
  • Resolution: Run npm audit fix to address most issues. Critical packages should be updated manually in a follow-up security PR.

Recommendation: Create a separate PR for security updates after this upgrade is merged to avoid mixing framework upgrades with dependency patches.

<EFBFBD>📝 Documentation

  • Created docs/UPGRADE_PLAN-upgrade-deps-react-node-20251028.md with phase-by-phase plan
  • Created .github/ISSUES/upgrade-deps-react-node-20251028.md (issue/PR template)
  • This CHANGELOG documents all completed work

🔧 Configuration Changes

  • backend/Dockerfile: Node 14 → Node 24
  • frontend/Dockerfile: Removed --legacy-peer-deps, uses clean npm install
  • frontend/Dockerfile.dev: New dev image with Node 18, nginx + CRA dev server
  • docker-compose.override.yml: Dev environment configuration
  • frontend/package.json: Updated all major framework versions
  • frontend/src/index.js: React 18 createRoot API
  • Multiple component files: MUI v5 migration (sx/styled)

⚠️ Known Issues / Notes

  • PostCSS deprecation warning from react-scripts 5.0.1 is harmless (no fix available)
  • Git push to remote blocked by SSH permission (local commits ready)

🚀 Next Steps (Pending)

  • Integration smoke tests (upload, download, slideshow)
  • Push branch to remote and open PR
  • Security audit (npm audit, CVE validation)
  • Verify production builds in CI
  • Merge PR after QA approval

Development Commands

Production Build & Run

# Build and run production containers
docker compose -f docker-compose.yml up --build -d

# Or use prod.sh script
./prod.sh

Development Mode (with live reload)

# Start dev environment with HMR
docker compose -f docker-compose.yml -f docker-compose.override.yml up --build -d

# Frontend available at: http://localhost:3000
# Backend available at: http://localhost:5000

# Tail logs
docker logs -f image-uploader-frontend-dev
docker logs -f image-uploader-backend-dev

# Stop dev environment
docker compose -f docker-compose.yml -f docker-compose.override.yml down

Update Dependencies

# Update browserslist database
docker exec image-uploader-frontend-dev npx update-browserslist-db@latest

# Install new packages (in dev container)
docker exec image-uploader-frontend-dev npm install <package-name>

# Rebuild containers after package.json changes
docker compose -f docker-compose.yml -f docker-compose.override.yml up --build -d