fix: improve photo authentication middleware for thumbnails
Test and Lint / backend-test (push) Successful in 1m14s
continuous-integration/drone/push Build is passing
Test and Lint / frontend-test (push) Successful in 2m5s
Version and Release / version-bump (push) Successful in 32s
Version and Release / trigger-drone (push) Successful in 3s
Test and Lint / backend-test (push) Successful in 1m14s
continuous-integration/drone/push Build is passing
Test and Lint / frontend-test (push) Successful in 2m5s
Version and Release / version-bump (push) Successful in 32s
Version and Release / trigger-drone (push) Successful in 3s
- Add eventId check from JWT token for thumbnail access - Better error logging for debugging authentication issues - Add admin debug endpoint to check photo existence - More permissive thumbnail access when valid gallery token exists This should help diagnose why photos are returning 404 errors in production. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,8 @@ async function photoAuth(req, res, next) {
|
|||||||
// Extract event slug from the path
|
// Extract event slug from the path
|
||||||
let eventSlug;
|
let eventSlug;
|
||||||
|
|
||||||
|
console.log('PhotoAuth middleware - path:', req.path);
|
||||||
|
|
||||||
// For thumbnails, we need to parse the filename to get the event info
|
// For thumbnails, we need to parse the filename to get the event info
|
||||||
if (req.path.startsWith('/thumb_')) {
|
if (req.path.startsWith('/thumb_')) {
|
||||||
// For now, we'll rely on JWT token for thumbnail access
|
// For now, we'll rely on JWT token for thumbnail access
|
||||||
@@ -26,9 +28,22 @@ async function photoAuth(req, res, next) {
|
|||||||
|
|
||||||
// Check if it's a gallery token
|
// Check if it's a gallery token
|
||||||
if (decoded.type === 'gallery') {
|
if (decoded.type === 'gallery') {
|
||||||
// For thumbnails, we accept any valid gallery token
|
// For thumbnails, we need to verify the token is for a valid event
|
||||||
if (!eventSlug) {
|
if (!eventSlug) {
|
||||||
const event = await db('events').where({ slug: decoded.eventSlug, is_active: formatBoolean(true) }).first();
|
// Extract event ID from the decoded token
|
||||||
|
if (decoded.eventId) {
|
||||||
|
const event = await db('events')
|
||||||
|
.where({ id: decoded.eventId, is_active: formatBoolean(true) })
|
||||||
|
.first();
|
||||||
|
if (event) {
|
||||||
|
req.event = event;
|
||||||
|
return next();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Fallback to slug
|
||||||
|
const event = await db('events')
|
||||||
|
.where({ slug: decoded.eventSlug, is_active: formatBoolean(true) })
|
||||||
|
.first();
|
||||||
if (event) {
|
if (event) {
|
||||||
req.event = event;
|
req.event = event;
|
||||||
return next();
|
return next();
|
||||||
@@ -36,7 +51,9 @@ async function photoAuth(req, res, next) {
|
|||||||
}
|
}
|
||||||
// For regular photos, check if token matches the event
|
// For regular photos, check if token matches the event
|
||||||
else if (decoded.eventSlug === eventSlug) {
|
else if (decoded.eventSlug === eventSlug) {
|
||||||
const event = await db('events').where({ slug: eventSlug, is_active: formatBoolean(true) }).first();
|
const event = await db('events')
|
||||||
|
.where({ slug: eventSlug, is_active: formatBoolean(true) })
|
||||||
|
.first();
|
||||||
if (event) {
|
if (event) {
|
||||||
req.event = event;
|
req.event = event;
|
||||||
return next();
|
return next();
|
||||||
@@ -46,18 +63,12 @@ async function photoAuth(req, res, next) {
|
|||||||
|
|
||||||
// Check if it's an admin token (admins can view all photos)
|
// Check if it's an admin token (admins can view all photos)
|
||||||
if (decoded.type === 'admin') {
|
if (decoded.type === 'admin') {
|
||||||
if (!eventSlug) {
|
// For both thumbnails and photos with admin token, allow access
|
||||||
// For thumbnails with admin token, allow access
|
|
||||||
return next();
|
return next();
|
||||||
}
|
}
|
||||||
const event = await db('events').where({ slug: eventSlug }).first();
|
|
||||||
if (event) {
|
|
||||||
req.event = event;
|
|
||||||
return next();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
// Token invalid, fall through to password check
|
// Token invalid, fall through to password check
|
||||||
|
console.error('JWT verification failed:', err.message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -68,8 +79,8 @@ async function photoAuth(req, res, next) {
|
|||||||
return res.status(401).json({ error: 'Authentication required' });
|
return res.status(401).json({ error: 'Authentication required' });
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no eventSlug (thumbnails), we require JWT token
|
// If no eventSlug (thumbnails), and we don't have valid auth yet, deny access
|
||||||
if (!eventSlug) {
|
if (!eventSlug && !password) {
|
||||||
return res.status(401).json({ error: 'Authentication required for thumbnails' });
|
return res.status(401).json({ error: 'Authentication required for thumbnails' });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -646,4 +646,24 @@ router.get('/:eventId/thumbnail/:photoId', adminAuth, async (req, res) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Debug endpoint to check photo existence
|
||||||
|
router.get('/:eventId/debug', adminAuth, async (req, res) => {
|
||||||
|
try {
|
||||||
|
const { eventId } = req.params;
|
||||||
|
|
||||||
|
const event = await db('events').where({ id: eventId }).first();
|
||||||
|
const photoCount = await db('photos').where({ event_id: eventId }).count('id as count').first();
|
||||||
|
const photos = await db('photos').where({ event_id: eventId }).limit(5);
|
||||||
|
|
||||||
|
res.json({
|
||||||
|
event: event || 'Not found',
|
||||||
|
photoCount: photoCount.count,
|
||||||
|
samplePhotos: photos,
|
||||||
|
storagePath: getStoragePath()
|
||||||
|
});
|
||||||
|
} catch (error) {
|
||||||
|
res.status(500).json({ error: error.message });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = router;
|
module.exports = router;
|
||||||
Reference in New Issue
Block a user