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
32 KiB
Changelog
[Unreleased] - Branch: feature/public-internal-hosts
🌐 Public/Internal Host Separation (November 25, 2025)
Backend
-
✅ Host-Based Access Control: Implemented
hostGatemiddleware 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) orHostheader - Environment variables:
PUBLIC_HOST,INTERNAL_HOST,ENABLE_HOST_RESTRICTION,TRUST_PROXY_HOPS
- Public host blocks internal routes:
-
✅ 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_typeinmanagement_audit_log - Tracks:
req.requestSource(public/internal) for all management actions - Database migration 009: Added source tracking columns
- New 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, ModerationPagesProtectedRoutecomponent: 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')whennavigator.clipboardunavailable - Fixes: "Cannot read properties of undefined (reading 'writeText')" on HTTP
- Works in non-HTTPS environments (local testing, HTTP-only deployments)
- Fallback to
-
✅ 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_HOPSdocker/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/hostssetup 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
- Solution: Created
- 🐛 Fixed: Webpack "Invalid Host header" error with custom hostnames
- Solution: Added
DANGEROUSLY_DISABLE_HOST_CHECK=truein.env.development
- Solution: Added
- 🐛 Fixed: Missing PUBLIC_HOST/INTERNAL_HOST in frontend env-config.js
- Solution: Added variables to
docker/dev/frontend/config/.env
- Solution: Added variables to
- 🐛 Fixed: Wrong navbar (Navbar instead of NavbarUpload) on 404 page for public host
- Solution: Conditional rendering
{hostConfig.isPublic ? <NavbarUpload /> : <Navbar />}
- Solution: Conditional rendering
- 🐛 Fixed: "Plattformen konnten nicht geladen werden" in UUID Management mode
- Solution: Added
/api/social-media/platformsto PUBLIC_ALLOWED_ROUTES
- Solution: Added
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_typecolumns - Environment: 5 new ENV variables for host configuration
- New files:
-
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)
- New files:
-
Production Impact:
- nginx-proxy-manager setup required for subdomain routing
- Must forward
X-Forwarded-Hostheader to backend - Set
TRUST_PROXY_HOPS=1when 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+requireCsrfmiddlewares, and exposedGET /auth/csrf-tokenfor clients. - ✅ New Auth Lifecycle: Added
GET /auth/setup/status,POST /auth/setup/initial-admin,POST /auth/login,POST /auth/logout,POST /auth/change-password, andPOST /api/admin/usersto support onboarding, login, rotation, and creating additional admins. - ✅ Admin Directory: Introduced
admin_userstable, repository, andAdminAuthService(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.jsonin nodemon watches, and expose Swagger UI reliably athttp://localhost:5001/api/docs/.
Frontend
- ✅ Admin Session Context: New
AdminSessionProvidermanages setup/login state, CSRF persistence, and guards moderation routes viaAdminSessionGate. - ✅ 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.mdto describe the new security model and CLI workflow. - ✅ Feature Documentation: Added
FeatureRequests/FEATURE_PLAN-security.md+FEATURE_TESTPLAN-security.mdoutlining 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 patterntests/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=testenvironment detection
- In-memory SQLite database (
-
✅ 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
requireAdminAuthmiddleware for Bearer token validation- Environment variable:
ADMIN_API_KEYfor 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
- Complete setup guide in
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/adminprefix - Documentation: Added comments explaining why order matters
- Problem: Generic routes (
-
✅ 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
- Wrapped
- 🐛 Fixed: Upload endpoint file validation checking
req.files.filebeforereq.filesexistence- Added
!req.filescheck before accessing.fileproperty
- Added
- 🐛 Fixed: Test uploads failing with EACCES permission denied
- Use
/tmp/directory in test mode instead ofdata/images/ - Dynamic path handling with
path.isAbsolute()check
- Use
- 🐛 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
-
Admin API Calls: Add Bearer token header
headers: { 'Authorization': `Bearer ${ADMIN_API_KEY}` } -
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/*)
- Consent routes:
-
Error Handling: Handle 403 responses for missing/invalid authentication
-
Environment Configuration: Add
REACT_APP_ADMIN_API_KEYto 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
- New files:
-
Configuration Files:
jest.config.js: Test configuration with coverage thresholds.env.example: Added ADMIN_API_KEY documentationpackage.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 modesGroupMetadataEditor.js(146 lines): Metadata editing with edit/upload/moderate modesImageDescriptionManager.js(175 lines): Batch image descriptions with manage/moderate modesDeleteGroupButton.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_tokencolumn - Token-based authentication for all management operations
- Format validation (UUID v4 regex)
- Tokens stored in
-
✅ Management APIs: Complete self-service functionality
GET /api/manage/:token- Load group dataPUT /api/manage/:token/consents- Revoke/restore consentsPUT /api/manage/:token/metadata- Edit title/descriptionPUT /api/manage/:token/images/descriptions- Batch update descriptionsPOST /api/manage/:token/images- Add images (max 50 per group)DELETE /api/manage/:token/images/:imageId- Delete single imageDELETE /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_logtable - 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 behaviormode="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
🔐 Social Media Consent Management (November 9-10, 2025)
Backend Features (Phase 1 Backend - Nov 9)
-
✅ Database Migrations:
- Migration 005: Added consent fields to
groupstabledisplay_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_platformstable (configurable platforms)group_social_media_consentstable (per-group, per-platform consents)- Revocation tracking:
revoked,revoked_timestampcolumns
- GDPR-compliant: Old groups keep
display_in_workshop = 0(no automatic consent)
- Migration 005: Added consent fields to
-
✅ 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 statusGET /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_workshopnot 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.jsfor 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
- Custom hook
-
✅ 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
- New file:
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_logtable 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 thresholdSchedulerService.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 historyGroupRepository.js- New methods:findUnapprovedGroupsOlderThan()- Query old unapproved groupsgetGroupStatistics()- Gather metadata before deletiondeleteGroupCompletely()- Transactional deletion with CASCADE
-
✅ API Endpoints: Admin API routes (
/api/admin/*)GET /deletion-log?limit=N- Recent deletions with paginationGET /deletion-log/all- Complete deletion historyGET /deletion-log/stats- Statistics with formatted file sizesPOST /cleanup/trigger- Manual cleanup trigger (testing)GET /cleanup/preview- Dry-run preview of deletions
-
✅ Dependencies: Added
node-cron@3.0.3for 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
sweetalert2for user feedback
Infrastructure
- ✅ Nginx Configuration: Updated routes for admin API
- Dev + Prod configs updated
/api/adminproxy 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 scriptbackend/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_descriptioncolumn toimagestable (TEXT, nullable)- Automatic migration on server startup
- Index created for performance optimization
- Backward compatible with existing images
-
✅ Repository Layer: Extended
GroupRepository.jswith description methodsupdateImageDescription()- Update single image descriptionupdateBatchImageDescriptions()- Batch update multiple descriptions- Validation: Max 200 characters enforced
createGroup()now acceptsimageDescriptionfield
-
✅ API Endpoints: New REST endpoints for description management
PATCH /groups/:groupId/images/:imageId- Update single descriptionPATCH /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/batchacceptsdescriptionsarray- Descriptions matched to images by filename
- Automatic truncation if exceeding limit
Frontend
-
✅ Core Components: Enhanced
ImageGalleryCardandImageGallery- 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/Dockerfileto usenode:24base image - Verified sqlite3 compatibility and DB initialization
- Backend server runs successfully on port 5000
- Updated
Frontend
-
✅ React: Upgraded from React 17 → React 18.3.1
- Updated
reactandreact-domto^18.3.1 - Migrated root rendering API from
ReactDOM.render()tocreateRoot()insrc/index.js - Updated
react-scriptsto5.0.1
- Updated
-
✅ React Router: Migrated from v5 → v6.28.0 (installed v6.30.1 in dev)
- Replaced
<Switch>with<Routes> - Updated route definitions to use
elementprop instead ofcomponent - Migrated navigation hooks:
useHistory()→useNavigate() - Updated all
<Route>paths and nested routing logic
- Replaced
-
✅ 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/stylesafter completing component migration - Converted styling from
makeStylestosxprop for components:UploadProgress.jsDescriptionInput.jsMultiImageDropzone.jsMultiUploadPage.jsSlideshowPage.jsGroupsOverviewPage.js- Other components using MUI v5 styled/sx patterns
- Installed
Dependencies & Cleanup
-
✅ Lottie Animation: Replaced
react-lottiewithlottie-react(v2.4.0)- Removed peer dependency conflict with older React versions
- Updated
Loading.jscomponent to use new API
-
✅ Removed
--legacy-peer-depsfromfrontend/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.ymlandfrontend/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 (
./frontendand./backend) - Separate
node_modulesvolumes 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-scripts5.0.1 transitive dependencies (postcss@8.5.6) - No action required - will be resolved in future react-scripts updates
- Warning originates from
<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 vulnerabilitiesfollow-redirects: Information exposure, improper URL handlingansi-regex,decode-uri-component: ReDoS vulnerabilities
- Moderate severity:
@babel/runtime-corejs3: Inefficient RegExp complexitywebpack-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 fixto 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.mdwith 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 24frontend/Dockerfile: Removed--legacy-peer-deps, uses clean npm installfrontend/Dockerfile.dev: New dev image with Node 18, nginx + CRA dev serverdocker-compose.override.yml: Dev environment configurationfrontend/package.json: Updated all major framework versionsfrontend/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