From ba4ca1479d3bec1c0f0a81343c5d65ad52f3963d Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 10 Oct 2025 10:15:31 +0100 Subject: [PATCH 1/4] Copy json news file to build output x3 https://github.com/the-draupnir-project/Draupnir/issues/972. Sorry everypony. We didn't want to use JSON Modules because that sounds weird and this seems like a safer bet for now. --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index 34a72c3d..9793bfe3 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "license": "AFL-3.0", "private": true, "scripts": { - "build": "tsc --project test/tsconfig.json && tsc > /dev/null 2>&1", + "build": "tsc --project test/tsconfig.json && tsc > /dev/null 2>&1 && corepack yarn copy-assets", + "copy-assets": "cp src/protections/DraupnirNews/news.json lib/protections/DraupnirNews/news.json", "postbuild": "corepack yarn describe-version", "describe-version": "(git describe > version.txt.tmp && mv version.txt.tmp version.txt) || true && rm -f version.txt.tmp", "remove-tests-from-lib": "rm -rf lib/test/ && cp -r lib/src/* lib/ && rm -rf lib/src/", From da78010afbbaefbce454878dc8abe542bad875d2 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 10 Oct 2025 10:22:06 +0100 Subject: [PATCH 2/4] Enable DraupnirNews by default. https://github.com/the-draupnir-project/planning/issues/60. --- .../DefaultEnabledProtectionsMigration.ts | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/protections/DefaultEnabledProtectionsMigration.ts b/src/protections/DefaultEnabledProtectionsMigration.ts index 732ede49..54df014f 100644 --- a/src/protections/DefaultEnabledProtectionsMigration.ts +++ b/src/protections/DefaultEnabledProtectionsMigration.ts @@ -187,4 +187,25 @@ export const DefaultEnabledProtectionsMigration = [DRAUPNIR_SCHEMA_VERSION_KEY]: toVersion, }); }, + async function enableDraupnirNews(input, toVersion) { + if (!Value.Check(MjolnirEnabledProtectionsEvent, input)) { + return ActionError.Result( + `The data for ${MjolnirEnabledProtectionsEventType} is corrupted.` + ); + } + const enabledProtections = new Set(input.enabled); + const protection = findProtection("DraupnirNews"); + if (protection === undefined) { + const message = `Cannot find the DraupnirNews protection`; + return ActionException.Result(message, { + exception: new TypeError(message), + exceptionKind: ActionExceptionKind.Unknown, + }); + } + enabledProtections.add(protection.name); + return Ok({ + enabled: [...enabledProtections], + [DRAUPNIR_SCHEMA_VERSION_KEY]: toVersion, + }); + }, ]); From b365ac9244eaed8792574145eb4656c0de9f6708 Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 10 Oct 2025 11:28:30 +0100 Subject: [PATCH 3/4] Make sure that we only store seen news when there is unseen news. https://github.com/the-draupnir-project/planning/issues/60 --- src/protections/DraupnirNews/DraupnirNews.tsx | 4 ++ test/unit/protections/DraupnirNewsTest.ts | 43 +++++++++++++++++++ 2 files changed, 47 insertions(+) diff --git a/src/protections/DraupnirNews/DraupnirNews.tsx b/src/protections/DraupnirNews/DraupnirNews.tsx index 1071dabe..ee80cb63 100644 --- a/src/protections/DraupnirNews/DraupnirNews.tsx +++ b/src/protections/DraupnirNews/DraupnirNews.tsx @@ -98,6 +98,9 @@ export class DraupnirNewsLifecycle { allNews, this.seenNewsIDs ); + if (unseenNews.length === 0) { + return; + } const notifiedNews = DraupnirNewsHelper.removeUnseenNews( allNews, this.seenNewsIDs @@ -128,6 +131,7 @@ const FSNews = (() => { })(); async function fetchNews(newsURL: string): Promise> { + log.debug("Fetching remote news", newsURL); return await fetch(newsURL, { method: "GET", headers: { diff --git a/test/unit/protections/DraupnirNewsTest.ts b/test/unit/protections/DraupnirNewsTest.ts index f15db5d8..f3b06e01 100644 --- a/test/unit/protections/DraupnirNewsTest.ts +++ b/test/unit/protections/DraupnirNewsTest.ts @@ -5,6 +5,7 @@ import { Ok, ResultError } from "@gnuxie/typescript-result"; import { DraupnirNewsBlob, + DraupnirNewsItem, DraupnirNewsLifecycle, } from "../../../src/protections/DraupnirNews/DraupnirNews"; import expect from "expect"; @@ -98,4 +99,46 @@ describe("DraupnirNewsTest", function () { await newsLifecycle.checkForNews(); expect(notifiedNews.length).toBe(1); }); + it("Test news is only stored when there is unseen news", async function () { + const fileSystemNews = { + news: [], + } satisfies DraupnirNewsBlob; + const seenNews = new Set(); + const storeOperations: DraupnirNewsItem[][] = []; + const notifiedNews: string[] = []; + const newsLifecycle = new DraupnirNewsLifecycle( + seenNews, + fileSystemNews, + async (allNews) => { + allNews.forEach((item) => seenNews.add(item.news_id)); + storeOperations.push(allNews); + return Ok(undefined); + }, + async () => + Ok({ + news: [ + { + news_id: "1", + matrix_event_content: { + body: "Announcing release v3.0.0!! wohoo", + msgtype: "m.text", + }, + }, + ], + }), + async (item) => { + notifiedNews.push(item.news_id); + return Ok(undefined); + } + ); + expect(seenNews.size).toBe(0); + expect(notifiedNews.length).toBe(0); + await newsLifecycle.checkForNews(); + expect(seenNews.size).toBe(1); + expect(notifiedNews.length).toBe(1); + expect(storeOperations.length).toBe(1); + await newsLifecycle.checkForNews(); + expect(notifiedNews.length).toBe(1); + expect(storeOperations.length).toBe(1); + }); }); From 2cd0d24b6b0ca5455c067cb9e76eb82c442f1edb Mon Sep 17 00:00:00 2001 From: gnuxie Date: Fri, 10 Oct 2025 12:11:07 +0100 Subject: [PATCH 4/4] Update to MPS v4.1.0 to fix protections looping on self changes. https://github.com/the-draupnir-project/Draupnir/issues/963 https://github.com/the-draupnir-project/planning/issues/60 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 9793bfe3..81418e5c 100644 --- a/package.json +++ b/package.json @@ -64,7 +64,7 @@ "jsdom": "^24.0.0", "matrix-appservice-bridge": "^10.3.1", "matrix-bot-sdk": "npm:@vector-im/matrix-bot-sdk@^0.7.1-element.6", - "matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@4.0.0", + "matrix-protection-suite": "npm:@gnuxie/matrix-protection-suite@4.1.0", "matrix-protection-suite-for-matrix-bot-sdk": "npm:@gnuxie/matrix-protection-suite-for-matrix-bot-sdk@3.12.0", "pg": "^8.8.0", "yaml": "^2.3.2" diff --git a/yarn.lock b/yarn.lock index 03def2d5..2b1c2393 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2606,10 +2606,10 @@ matrix-appservice@^2.0.0: "@gnuxie/typescript-result" "^1.0.0" await-lock "^2.2.2" -"matrix-protection-suite@npm:@gnuxie/matrix-protection-suite@4.0.0": - version "4.0.0" - resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite/-/matrix-protection-suite-4.0.0.tgz#86d9522397f79672dd65077c1c4d344bcc63094e" - integrity sha512-NmkqQMgPr3mDyg8KYfSx9Prb/T1RgGG/O2ASXmJzGfEBTfWf9NeXiDeG4VqgIqJkuoxvp8vbk1/nRLcYnMDDuQ== +"matrix-protection-suite@npm:@gnuxie/matrix-protection-suite@4.1.0": + version "4.1.0" + resolved "https://registry.yarnpkg.com/@gnuxie/matrix-protection-suite/-/matrix-protection-suite-4.1.0.tgz#1df1a27c325f4945ccd7833129f87d9893b472b8" + integrity sha512-mWZT67adNefRlML8FjLOzAXRcdfoTyFAsfS/e9cmnGk0UQ+yj8mSiX9N2/Clv6N2jpT39LUzhPv9o2PLRp0ELg== dependencies: "@gnuxie/typescript-result" "^1.0.0" await-lock "^2.2.2"