Keep a feed's items and files to the people who subscribe to it (#129)
Routes that take a feed or an enclosure id did not check who was asking. Anyone signed in could
read any feed's items through GET /api/feeds/{id}/entries, a paid feed's included, with the
addresses of its files, which can carry the subscriber's key: the Directory leaves such feeds
out for that reason, and this route handed them back to whoever guessed the id, a slug of the
title. In production it answered 25 items of a feed the asking account does not subscribe to.
/media/{id} served any downloaded file by its sequential id, POST /api/enclosures/{id}/download
and /api/feeds/{id}/download-latest queued any feed's downloads, and DELETE
/api/enclosures/{id}?force=true deleted any file.
Each now answers 404, "you do not subscribe to that feed", unless the person subscribes to it.
A feed inside an OPML has a subscription row of its own for everyone subscribed to the OPML, so
that holds for those feeds too. Found while adding the Directory's feed page (#128), which has
its own route that answers only for listed feeds and carries no files.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -812,7 +812,7 @@ test('ipx import subscribes the admin, and ipx export writes the feeds out', asy
|
||||
expect(xml).toContain('http://127.0.0.1:8792/two.xml');
|
||||
});
|
||||
|
||||
test('the Directory lists what everyone here reads, the most subscribed first, but never a private feed', async ({ browser }) => {
|
||||
test('the Directory lists what everyone here reads, the most subscribed first, but never a private feed', async ({ browser, page }) => {
|
||||
const { execFileSync } = require('child_process');
|
||||
const setup = require('./global-setup');
|
||||
const env = {
|
||||
@@ -919,6 +919,17 @@ test('the Directory lists what everyone here reads, the most subscribed first, b
|
||||
expect(preview).toContain('First Episode');
|
||||
expect(preview).not.toContain('.mp3');
|
||||
expect((await piper.request.get('/api/directory/paid-show')).status()).toBe(404);
|
||||
// Nor does anything else give a feed's items or files to someone who does not subscribe (#129).
|
||||
expect((await piper.request.get('/api/feeds/test-show/entries')).status()).toBe(404);
|
||||
expect((await piper.request.get('/api/feeds/paid-show/entries')).status()).toBe(404);
|
||||
const pics = await page.evaluate(() => api('/api/feeds/picture-blog/entries'));
|
||||
const file = pics.entries.flatMap(e => e.enclosures).find(x => x.path);
|
||||
expect(file).toBeTruthy();
|
||||
expect((await page.request.get(`/media/${file.id}`)).status()).toBe(200);
|
||||
expect((await piper.request.get(`/media/${file.id}`)).status()).toBe(404);
|
||||
expect((await piper.request.post(`/api/enclosures/${file.id}/download`)).status()).toBe(404);
|
||||
expect((await piper.request.delete(`/api/enclosures/${file.id}?force=true`)).status()).toBe(404);
|
||||
expect((await piper.request.post('/api/feeds/picture-blog/download-latest', { data: { count: 1 } })).status()).toBe(404);
|
||||
|
||||
// Add a feed is for an address; the Directory is where you browse (issue #30).
|
||||
await piper.locator('#addFeed').click();
|
||||
@@ -935,6 +946,7 @@ test('the Directory lists what everyone here reads, the most subscribed first, b
|
||||
|
||||
// Everyone counts, you included: it stays listed, marked as yours, with one more subscriber.
|
||||
expect(await row()).toMatchObject({ subscribed: true, subscribers: before.subscribers + 1 });
|
||||
expect((await piper.request.get('/api/feeds/test-show/entries')).status()).toBe(200);
|
||||
await piper.locator('#feedlist .place', { hasText: 'Directory' }).click();
|
||||
await expect(chart.filter({ hasText: 'Test Show' }).locator('[title^="Subscribed"]')).toBeVisible();
|
||||
await expect(chart.filter({ hasText: 'Test Show' }).locator('button[title="Subscribe"]')).toHaveCount(0);
|
||||
|
||||
Reference in New Issue
Block a user