diff --git a/docker/backend/src/server.ts b/docker/backend/src/server.ts index 5e80d72..df7bb9c 100644 --- a/docker/backend/src/server.ts +++ b/docker/backend/src/server.ts @@ -494,7 +494,7 @@ app.post('/api/open-explorer', async (req, reply) => { // a beacon from every page, so it must never be a way to probe who is signed in // — it answers 204 whatever happens and echoes nothing back. const allowTrack = limiter(300, 60_000); -app.post('/api/events', async (req, reply) => { +const handleEventTrack = async (req: Parameters[1] extends (req: infer R, ...args: any[]) => any ? R : any, reply: any) => { const b = bodyOf(req); const ip = clientIp(req); if (!b || !isEventKind(b.kind) || !allowTrack(ip || 'unknown')) return reply.status(204).send(); @@ -519,7 +519,9 @@ app.post('/api/events', async (req, reply) => { device: ua.device, }); return reply.status(204).send(); -}); +}; +app.post('/api/events', handleEventTrack); +app.post('/api/pulse', handleEventTrack); // The film strip's ratings. Public and unauthenticated for the same reason the // counter is: any visitor may score a frame once, and the vote is held against diff --git a/docker/frontend/src/track.ts b/docker/frontend/src/track.ts index 6608855..8074198 100644 --- a/docker/frontend/src/track.ts +++ b/docker/frontend/src/track.ts @@ -3,7 +3,7 @@ // control, so it doubles as the feature's name. Nothing here may break the app: // every path is wrapped, a refused beacon is simply not counted, and a visitor // who asked not to be tracked is left alone. -const ENDPOINT = '/api/events'; +const ENDPOINT = '/api/pulse'; type Kind = 'view' | 'click'; diff --git a/docker/recipescam-images.tar.gz.sha256 b/docker/recipescam-images.tar.gz.sha256 index ac8de3e..0df1abb 100644 --- a/docker/recipescam-images.tar.gz.sha256 +++ b/docker/recipescam-images.tar.gz.sha256 @@ -1 +1 @@ -f258217d804e6ee5c0720730b284e1c8045a6692758aeb0570723239e2974617 recipescam-images.tar.gz +b00e823e83ef29a57ba7f479edcc89de34fc2dd9bec7d796ba95cbfa680da7a2 recipescam-images.tar.gz