diff --git a/install/package.json b/install/package.json index f667307aa2..dc84d69c28 100644 --- a/install/package.json +++ b/install/package.json @@ -42,7 +42,7 @@ "ace-builds": "1.43.6", "archiver": "7.0.1", "async": "3.2.6", - "autoprefixer": "10.4.27", + "autoprefixer": "10.5.0", "bcryptjs": "3.0.3", "benchpressjs": "2.5.5", "body-parser": "2.2.2", @@ -90,7 +90,7 @@ "jsonwebtoken": "9.0.3", "lodash": "4.18.1", "logrotate-stream": "0.2.9", - "lru-cache": "11.3.3", + "lru-cache": "11.3.5", "mime": "3.0.0", "mkdirp": "3.0.1", "mongodb": "7.1.1", diff --git a/src/activitypub/blocklists.js b/src/activitypub/blocklists.js index 042ce2cfc5..56be264079 100644 --- a/src/activitypub/blocklists.js +++ b/src/activitypub/blocklists.js @@ -6,9 +6,9 @@ const db = require('../database'); const request = require('../request'); const activitypub = module.parent.exports; -const blocklists = module.exports; +const Blocklists = module.exports; -blocklists.list = async () => { +Blocklists.list = async () => { const blocklists = await db.getSortedSetMembers('blocklists'); const counts = await db.sortedSetsCard(blocklists.map(blocklist => `blocklist:${blocklist}`)); @@ -17,7 +17,7 @@ blocklists.list = async () => { }); }; -blocklists.get = async (url) => { +Blocklists.get = async (url) => { const domains = await db.getSortedSetMembers(`blocklist:${url}`); return { @@ -26,23 +26,23 @@ blocklists.get = async (url) => { }; }; -blocklists.add = async (url) => { +Blocklists.add = async (url) => { const now = Date.now(); await Promise.all([ db.sortedSetAdd('blocklists', now, url), - blocklists.refresh(url), + Blocklists.refresh(url), ]); }; -blocklists.remove = async (url) => { +Blocklists.remove = async (url) => { await Promise.all([ db.sortedSetRemove('blocklists', url), db.delete(`blocklist:${url}`), ]); }; -blocklists.refresh = async (url) => { +Blocklists.refresh = async (url) => { activitypub.helpers.log(`[blocklists/refresh] Processing ${url}`); const { body: csv } = await request.get(url); @@ -69,8 +69,8 @@ blocklists.refresh = async (url) => { return records.length; }; -blocklists.check = async (domain) => { - const blocklists = await blocklists.list(); +Blocklists.check = async (domain) => { + const blocklists = await Blocklists.list(); let present = await db.isMemberOfSortedSets(blocklists.map(({ url }) => `blocklist:${url}`), domain); present = present.reduce((memo, present) => memo || present, false); diff --git a/src/activitypub/index.js b/src/activitypub/index.js index 4dea4edd40..dd39ebb979 100644 --- a/src/activitypub/index.js +++ b/src/activitypub/index.js @@ -499,10 +499,10 @@ ActivityPub.record.send = async ({ type, target }) => { ]); }; -ActivityPub.record.sendError = async ({ payload, target, error }) => { +ActivityPub.record.sendError = async ({ payload, uri, error }) => { const { id } = payload; const now = Date.now(); - const { hostname } = new URL(target); + const { hostname } = new URL(uri); await Promise.all([ db.sortedSetAdd('ap.errors', now, id), db.setObject(`ap.errors:${id}`, { diff --git a/test/activitypub/blocklists.js b/test/activitypub/blocklists.js index 33408df8c7..cc06da8ec7 100644 --- a/test/activitypub/blocklists.js +++ b/test/activitypub/blocklists.js @@ -6,17 +6,21 @@ const path = require('path'); const db = require('../mocks/databasemock'); const request = require('../../src/request'); +const meta = require('../../src/meta'); +const install = require('../../src/install'); const activitypub = require('../../src/activitypub'); describe('ActivityPub blocklists', () => { - before(async () => { + before(async function () { meta.config.activitypubEnabled = 1; meta.config.activitypubAllowLoopback = 1; await install.giveWorldPrivileges(); + this.getHandler = request.get; }); - after(() => { + after(function () { delete meta.config.activitypubEnabled; + request.get = this.getHandler; }); describe('blocklists.list()', () => { @@ -106,7 +110,7 @@ describe('ActivityPub blocklists', () => { // Verify the blocklist was added and refreshed const result = await activitypub.blocklists.get(url); - assert.strictEqual(result.count, 0); // Empty initially + assert.strictEqual(result.count, 2); }); }); @@ -134,66 +138,78 @@ describe('ActivityPub blocklists', () => { }); describe('blocklists.refresh()', () => { - it('should process a valid CSV', async () => { - const url = 'https://example.com/blocklist.csv'; - await activitypub.blocklists.add(url); + before(function () { + this.url = 'https://example.com/blocklist.csv'; + }); + + afterEach(async function () { + await activitypub.blocklists.remove(this.url); + }); + + it('should process a valid CSV', async function () { + await activitypub.blocklists.add(this.url); const csvData = '#domain,#severity\nexample.com,1\nexample.org,2\nsilence.example.com,2'; const mockResponse = { body: csvData }; request.get = () => mockResponse; - const result = await activitypub.blocklists.refresh(url); + const result = await activitypub.blocklists.refresh(this.url); assert.strictEqual(result, 3); }); - it('should return 0 for empty CSV', async () => { - const url = 'https://example.com/blocklist.csv'; - await activitypub.blocklists.add(url); + it('should return 0 for empty CSV', async function () { + await activitypub.blocklists.add(this.url); const csvData = ''; const mockResponse = { body: csvData }; request.get = () => mockResponse; - const result = await activitypub.blocklists.refresh(url); + const result = await activitypub.blocklists.refresh(this.url); assert.strictEqual(result, 0); }); - it('should return 0 on parse error', async () => { - const url = 'https://example.com/blocklist.csv'; - await activitypub.blocklists.add(url); + it('should return 0 on parse error', async function () { + await activitypub.blocklists.add(this.url); const csvData = 'invalid,csv,data'; const mockResponse = { body: csvData }; request.get = () => mockResponse; - const result = await activitypub.blocklists.refresh(url); + const result = await activitypub.blocklists.refresh(this.url); assert.strictEqual(result, 0); }); - it('should handle severity levels correctly', async () => { - const url = 'https://example.com/blocklist.csv'; - await activitypub.blocklists.add(url); + it('should handle severity levels correctly', async function () { + await activitypub.blocklists.add(this.url); const csvData = '#domain,#severity\nexample.com,1\nsilence.example.com,2'; const mockResponse = { body: csvData }; request.get = () => mockResponse; - await activitypub.blocklists.refresh(url); + await activitypub.blocklists.refresh(this.url); - const result = await activitypub.blocklists.get(url); + const result = await activitypub.blocklists.get(this.url); assert.strictEqual(result.count, 2); }); }); describe('blocklists.check()', () => { - it('should return true when domain is not blocked', async () => { - const url = 'https://example.com/blocklist.csv'; - await activitypub.blocklists.add(url); + async function clear () { + const url1 = 'https://example.com/blocklist1.csv'; + const url2 = 'https://example.com/blocklist2.csv'; + const url3 = 'https://example.com/blocklist.csv'; + await Promise.all([url1, url2, url3].map(async (url) => { + await activitypub.blocklists.remove(url); + })); + } + before(clear); + afterEach(clear); + it('should return true when domain is not blocked', async () => { const result = await activitypub.blocklists.check('example.com'); assert.strictEqual(result, true); @@ -218,8 +234,6 @@ describe('ActivityPub blocklists', () => { const url1 = 'https://example.com/blocklist1.csv'; const url2 = 'https://example.com/blocklist2.csv'; - await activitypub.blocklists.add(url1); - await activitypub.blocklists.add(url2); const csvData1 = '#domain,#severity\nblocked.com,1'; const csvData2 = '#domain,#severity\nblocked.org,1'; @@ -227,11 +241,10 @@ describe('ActivityPub blocklists', () => { const mockResponse1 = { body: csvData1 }; const mockResponse2 = { body: csvData2 }; request.get = () => mockResponse1; - - await activitypub.blocklists.refresh(url1); + await activitypub.blocklists.add(url1); request.get = () => mockResponse2; - await activitypub.blocklists.refresh(url2); + await activitypub.blocklists.add(url2); const result = await activitypub.blocklists.check('example.com'); @@ -242,20 +255,17 @@ describe('ActivityPub blocklists', () => { const url1 = 'https://example.com/blocklist1.csv'; const url2 = 'https://example.com/blocklist2.csv'; - await activitypub.blocklists.add(url1); - await activitypub.blocklists.add(url2); - const csvData1 = '#domain,#severity\nexample.com,1'; const csvData2 = '#domain,#severity\nblocked.org,1'; const mockResponse1 = { body: csvData1 }; const mockResponse2 = { body: csvData2 }; - request.get = () => mockResponse1; - await activitypub.blocklists.refresh(url1); + request.get = () => mockResponse1; + await activitypub.blocklists.add(url1); request.get = () => mockResponse2; - await activitypub.blocklists.refresh(url2); + await activitypub.blocklists.add(url2); const result = await activitypub.blocklists.check('example.com');