Block uploads for demo user, restore PDF preview modal (v2.2.3)

- Demo user gets 403 on all upload endpoints (files, photos, cover, avatar)
- Admin uploads still work normally
- PDF export back in modal popup using srcdoc iframe
- Zero behavior change when DEMO_MODE is not set
This commit is contained in:
Maurice
2026-03-19 15:09:20 +01:00
parent 1a5c8cd385
commit c582a7b6c8
7 changed files with 50 additions and 16 deletions

View File

@@ -53,4 +53,11 @@ const adminOnly = (req, res, next) => {
next();
};
module.exports = { authenticate, optionalAuth, adminOnly };
const demoUploadBlock = (req, res, next) => {
if (process.env.DEMO_MODE === 'true' && req.user?.email === 'demo@nomad.app') {
return res.status(403).json({ error: 'Uploads are disabled in demo mode. Self-host NOMAD for full functionality.' });
}
next();
};
module.exports = { authenticate, optionalAuth, adminOnly, demoUploadBlock };

View File

@@ -7,7 +7,7 @@ const fs = require('fs');
const { v4: uuid } = require('uuid');
const fetch = require('node-fetch');
const { db } = require('../db/database');
const { authenticate } = require('../middleware/auth');
const { authenticate, demoUploadBlock } = require('../middleware/auth');
const router = express.Router();
const { JWT_SECRET } = require('../config');
@@ -243,7 +243,7 @@ router.get('/me/settings', authenticate, (req, res) => {
});
// POST /api/auth/avatar — upload avatar
router.post('/avatar', authenticate, avatarUpload.single('avatar'), (req, res) => {
router.post('/avatar', authenticate, demoUploadBlock, avatarUpload.single('avatar'), (req, res) => {
if (!req.file) return res.status(400).json({ error: 'No image uploaded' });
const current = db.prepare('SELECT avatar FROM users WHERE id = ?').get(req.user.id);

View File

@@ -4,7 +4,7 @@ const path = require('path');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const { db, canAccessTrip } = require('../db/database');
const { authenticate } = require('../middleware/auth');
const { authenticate, demoUploadBlock } = require('../middleware/auth');
const { broadcast } = require('../websocket');
const router = express.Router({ mergeParams: true });
@@ -72,7 +72,7 @@ router.get('/', authenticate, (req, res) => {
});
// POST /api/trips/:tripId/files
router.post('/', authenticate, upload.single('file'), (req, res) => {
router.post('/', authenticate, demoUploadBlock, upload.single('file'), (req, res) => {
const { tripId } = req.params;
const { place_id, description, reservation_id } = req.body;

View File

@@ -4,7 +4,7 @@ const path = require('path');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const { db, canAccessTrip } = require('../db/database');
const { authenticate } = require('../middleware/auth');
const { authenticate, demoUploadBlock } = require('../middleware/auth');
const router = express.Router({ mergeParams: true });
@@ -68,7 +68,7 @@ router.get('/', authenticate, (req, res) => {
});
// POST /api/trips/:tripId/photos
router.post('/', authenticate, upload.array('photos', 20), (req, res) => {
router.post('/', authenticate, demoUploadBlock, upload.array('photos', 20), (req, res) => {
const { tripId } = req.params;
const { day_id, place_id, caption } = req.body;

View File

@@ -4,7 +4,7 @@ const path = require('path');
const fs = require('fs');
const { v4: uuidv4 } = require('uuid');
const { db, canAccessTrip, isOwner } = require('../db/database');
const { authenticate } = require('../middleware/auth');
const { authenticate, demoUploadBlock } = require('../middleware/auth');
const { broadcast } = require('../websocket');
const router = express.Router();
@@ -139,7 +139,7 @@ router.put('/:id', authenticate, (req, res) => {
});
// POST /api/trips/:id/cover
router.post('/:id/cover', authenticate, uploadCover.single('cover'), (req, res) => {
router.post('/:id/cover', authenticate, demoUploadBlock, uploadCover.single('cover'), (req, res) => {
if (!isOwner(req.params.id, req.user.id))
return res.status(403).json({ error: 'Nur der Eigentümer kann das Titelbild ändern' });