- Updated README.md with Telegram features section in 'Latest Features'
- Added Telegram environment variables to Environment Variables table
- Updated FEATURE_PLAN-telegram.md: marked Phases 1-5 as completed
- Updated status table with completion dates (Phase 1-4: done, Phase 5: docs complete)
OpenAPI Documentation:
- Added swagger tags to reorder route (Management Portal)
- Added swagger tags to consent routes (Consent Management)
- Regenerated openapi.json with correct tags (no more 'default' category)
Environment Configuration:
- Updated .env.backend.example with Telegram variables and session secret
- Created docker/dev/.env.example with Telegram configuration template
- Created docker/prod/.env.example with production environment template
- Moved secrets from docker-compose.yml to .env files (gitignored)
- Changed docker/dev/docker-compose.yml to use placeholders: ${TELEGRAM_BOT_TOKEN}
Security Enhancements:
- Disabled test message on server start by default (TELEGRAM_SEND_TEST_ON_START=false)
- Extended pre-commit hook to detect hardcoded Telegram secrets
- Hook prevents commit if TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID are hardcoded
- All secrets must use environment variable placeholders
Phase 5 fully completed and documented.
- Integrate sendConsentChangeNotification() into management.js PUT /consents
- Integrate sendGroupDeletedNotification() into management.js DELETE /:token
- Refactor sendConsentChangeNotification() to accept structured changeData
- Add platform name lookup for social media consent notifications
- Non-blocking async notifications (won't fail consent changes on error)
Phase 4 complete: Tested successfully with:
- Workshop consent revoke → Telegram notification received
- Group deletion → Telegram notification received
Changes:
- Workshop consent: Shows action (revoke/restore) and new status
- Social media consent: Shows platform and action
- Deletion: Shows uploader, year, title, image count
🧪 Testing Infrastructure (45 tests, 100% passing)
- Implemented Jest + Supertest framework for automated testing
- Unit tests: 5 tests for auth middleware (100% coverage)
- Integration tests: 40 tests covering admin, consent, migration, upload APIs
- Test execution time: ~10 seconds for full suite
- Coverage: 26% statements, 15% branches (realistic start)
- In-memory SQLite database for isolated testing
- Singleton server pattern for fast test execution
- Automatic cleanup and teardown
🔒 Admin API Authentication
- Bearer token authentication for all admin endpoints
- requireAdminAuth middleware with ADMIN_API_KEY validation
- Protected routes: /api/admin/*, /api/system/migration/migrate|rollback
- Complete authentication guide in AUTHENTICATION.md
- HTTP 403 for missing/invalid tokens, 500 if not configured
- Ready for production with token rotation support
📋 API Route Documentation
- Single Source of Truth: backend/src/routes/routeMappings.js
- Comprehensive route overview in backend/src/routes/README.md
- Express routing order documented (specific before generic)
- Frontend integration guide with authentication examples
- OpenAPI auto-generation integrated
🐛 Bug Fixes
- Fixed SQLite connection not properly awaited (caused test hangs)
- Fixed upload validation checking req.files.file before req.files
- Fixed Express route order (consent before admin router)
- Fixed test environment using /tmp for uploads (permission issues)
📚 Documentation Updates
- Updated README.md with testing and authentication features
- Updated README.dev.md with testing section and API development guide
- Updated CHANGELOG.md with complete feature documentation
- Updated FEATURE_PLAN-autogen-openapi.md (status: 100% complete)
- Added frontend/MIGRATION-GUIDE.md for frontend team
🚀 Frontend Impact
Frontend needs to add Bearer token to all /api/admin/* calls.
See frontend/MIGRATION-GUIDE.md for detailed instructions.
Test Status: ✅ 45/45 passing (100%)
Backend: ✅ Production ready
Frontend: ⚠️ Migration required (see MIGRATION-GUIDE.md)
- Created new modular components:
* ConsentManager: Manages workshop + social media consents with individual save
* GroupMetadataEditor: Manages group metadata (title, description, name, year) with save
* ImageDescriptionManager: Manages image descriptions with batch save
* DeleteGroupButton: Standalone group deletion component
- Refactored ManagementPortalPage to use modular components:
* Each component in Paper box with heading inside (not outside)
* HTML buttons with CSS classes (btn btn-success, btn btn-secondary)
* Inline feedback with Material-UI Alert instead of SweetAlert2 popups
* Icons: 💾 save, ↩ discard, 🗑️ delete
* Individual save/discard functionality per component
- Enhanced ConsentCheckboxes component:
* Added children prop for flexible composition
* Conditional heading for manage mode inside Paper box
- Fixed DescriptionInput:
* Removed duplicate heading (now only in parent component)
- React state management improvements:
* Deep copy pattern for nested objects/arrays
* Sorted array comparison for order-insensitive change detection
* Set-based comparison for detecting removed items
* Initialization guard to prevent useEffect overwrites
- Bug fixes:
* Fixed image reordering using existing /api/groups/:groupId/reorder route
* Fixed edit mode toggle with unsaved changes warning
* Fixed consent state updates with proper object references
* Fixed uploadImageBatch signature to use object destructuring
* Removed unnecessary /api/manage/:token/reorder route from backend
Next: Apply same modular pattern to MultiUploadPage and ModerationGroupImagesPage
Audit-Logging System:
- Migration 007: management_audit_log table with indexes
- Tracks all management portal actions
- IP address, user-agent, request data logging
- Token masking (only first 8 chars stored)
- Success/failure tracking with error messages
ManagementAuditLogRepository:
- logAction() - Log management actions
- getRecentLogs() - Get last N logs
- getLogsByGroupId() - Get logs for specific group
- getFailedActionsByIP() - Security monitoring
- getStatistics() - Overview statistics
- cleanupOldLogs() - Maintenance (90 days retention)
Audit-Log Middleware:
- Adds res.auditLog() helper function
- Auto-captures IP, User-Agent
- Integrated into all management routes
- Non-blocking (errors don't fail main operation)
Admin API Endpoints:
- GET /api/admin/management-audit?limit=N
- GET /api/admin/management-audit/stats
- GET /api/admin/management-audit/group/:groupId
Tested:
✅ Migration executed successfully
✅ Audit logs written on token validation
✅ Admin API returns logs with stats
✅ Token masking working
✅ Statistics accurate
Rate-Limiting:
- IP-based: 10 requests per hour per IP
- Applies to all /api/manage/* routes
- Returns 429 Too Many Requests when limit exceeded
- Automatic cleanup of expired records (>1h old)
Brute-Force Protection:
- Tracks failed token validation attempts
- After 20 failed attempts: IP banned for 24 hours
- Returns 403 Forbidden for banned IPs
- Integrated into GET /api/manage/:token route
Technical Implementation:
- Created backend/src/middlewares/rateLimiter.js
- In-memory storage with Map() for rate limit tracking
- Separate Map() for brute-force detection
- Middleware applied to all management routes
- Token validation failures increment brute-force counter
Tested:
✅ Rate limit blocks after 10 requests
✅ 429 status code returned correctly
✅ Middleware integration working
✅ IP-based tracking functional
Fixed Task 8 (Delete Group API):
- Changed deletionLogRepository.logDeletion() to createDeletionEntry()
- Use correct parameters matching DeletionLogRepository schema
- Deletion now works: group, images, files, consents all removed
- deletion_log entry created with proper data
Tested:
✅ Group deletion with valid token
✅ 404 for invalid/missing tokens
✅ Files deleted (original + preview)
✅ DB records deleted via CASCADE
✅ Deletion log entry created
All 8 Backend Management API tasks complete!
Backend Management API implementation for self-service user portal:
✅ Task 2: Token Generation (already implemented in Phase 1)
- UUID v4 generated at upload
- Stored in groups.management_token
- Returned in upload response
✅ Task 3: Token Validation API
- GET /api/manage/:token
- Validates token and loads complete group data
- Returns group with images, consents, metadata
- 404 for invalid/missing tokens
✅ Task 4: Consent Revocation API
- PUT /api/manage/:token/consents
- Revoke/restore workshop consent
- Revoke/restore social media platform consents
- Sets revoked=1, revoked_timestamp
- Full error handling and validation
✅ Task 5: Metadata Edit API
- PUT /api/manage/:token/metadata
- Update title, description, name
- Supports partial updates
- Automatically sets approved=0 (returns to moderation)
✅ Task 6: Add Images API
- POST /api/manage/:token/images
- Upload new images to existing group
- Calculates correct upload_order
- Sets approved=0 on changes
- Max 50 images per group validation
- Preview generation support
✅ Task 7: Delete Image API
- DELETE /api/manage/:token/images/:imageId
- Deletes original and preview files
- Removes DB entry
- Sets approved=0 if group was approved
- Prevents deletion of last image
⏳ Task 8: Delete Group API (in progress)
- DELETE /api/manage/:token route created
- Integration with existing GroupRepository.deleteGroup
- Needs testing
Technical Changes:
- Created backend/src/routes/management.js
- Added getGroupByManagementToken() to GroupRepository
- Registered /api/manage routes in index.js
- Installed uuid package for token generation
- All routes use token validation helper
- Docker-only development workflow
Tested Features:
- Token validation with real uploads
- Workshop consent revoke/restore
- Social media consent management
- Metadata updates (full and partial)
- Image upload with multipart/form-data
- Image deletion with file cleanup
- Error handling and edge cases