borogove

created pr with borogove/multi-dm.1 on 2026-11-09T19:47:55Z · by 9e834e0d
added borogove/multi-dm.2 on 2026-11-10T19:08:22Z · by 9e834e0d
1: 0ef2769 = 1: 41e89c8 Use to for chatId if not in recipients
2: 90e5a6a = 2: c323e3d clone should clone attributes
3: d86ea28 = 3: a1199ae Actually send to all recipients
4: 1c1061f ! 4: 94bf87d Never add self as counterpart
5: 9c8aa41 = 5: 32b9fad Extended addressing for sent messages specifies all recipients
6: 2da9124 = 6: ce4d9e1 Always add all recipients to outbound message
7: e7db006 = 7: 350343e Use a shared helper for adding extended addressing
8: 4530ece = 8: 40f662a Add startMultiChat to create multiDMs
9: 6810ba9 = 9: 8043c53 Never include ourselves in incoming chat ids
-: ------- > 10: 68e7246 Cannot MAM or bookmark a multiDM
cmds
checkout latest patchset:
ssh pr.pico.sh pull borogove:multi-dm | git am -3
checkout specific patchset revision:
ssh pr.pico.sh pull borogove:multi-dm [rev] | git am -3
add changes to patch request:
git format-patch main --stdout | ssh pr.pico.sh borogove:multi-dm
add comment to patch request:
ssh pr.pico.sh comment borogove:multi-dm "lgtm!"
+3 -3 borogove/Chat.hx #
......@@ -1394,16 +1394,16 @@ class DirectChat extends Chat {
13941394 if (e2eePreference == Default) e2eePreference = client.outgoingE2EEPreference[0];
13951395 #if NO_OMEMO
13961396 if (e2eePreference != NoE2EE) throw "Selected E2EE preference unsupported";
1397- return Promise.resolve(stanza);
1397+ return Promise.resolve(clone);
13981398 #else
13991399 switch (e2eePreference) {
14001400 case OMEMO:
14011401 // As written this falls back to NoE2EE if allowed
1402- return client.omemo.encryptMessage([JID.parse(counterpart)], stanza).then((encryptedStanza) -> {
1402+ return client.omemo.encryptMessage([JID.parse(counterpart)], clone).then((encryptedStanza) -> {
14031403 return Promise.resolve(encryptedStanza);
14041404 });
14051405 case NoE2EE:
1406- return Promise.resolve(stanza);
1406+ return Promise.resolve(clone);
14071407 case Default:
14081408 throw "Impossible";
14091409 }
+51 -0 test/TestChat.hx #
......@@ -1166,6 +1166,57 @@ class TestChat extends utest.Test {
11661166 chat.sendMessage(builder, borogove.Chat.OutgoingE2EEPreference.OMEMO);
11671167 }
11681168 #end
1169+
1170+ public function testSendMessageExtendedMultiDMSendsToEachParticipant(async: Async) {
1171+ final persistence = new RecordingPersistence();
1172+ final client = new Client("me@example.com", persistence);
1173+ final chat = client.getDirectChat("bob@example.com\ncarol@example.com");
1174+ final sent: Array<Stanza> = [];
1175+
1176+ client.stream.on("sendStanza", (stanza: Stanza) -> {
1177+ if (stanza.name != "message" || stanza.getChildText("body") != "hello") return EventUnhandled;
1178+ sent.push(stanza);
1179+ if (sent.length < 2) return EventUnhandled;
1180+
1181+ final tos = sent.map(s -> s.attr.get("to"));
1182+ tos.sort(Reflect.compare);
1183+ Assert.same(["bob@example.com", "carol@example.com"], tos);
1184+ for (s in sent) {
1185+ final addresses = s.getChild("addresses", "http://jabber.org/protocol/address");
1186+ Assert.notNull(addresses);
1187+ if (addresses != null) {
1188+ final jids = addresses.allTags("address").map(a -> a.attr.get("jid"));
1189+ jids.sort(Reflect.compare);
1190+ Assert.same(["bob@example.com", "carol@example.com"], jids);
1191+ }
1192+ }
1193+
1194+ Assert.equals(1, persistence.storedMessages.length);
1195+ if (persistence.storedMessages.length > 0) {
1196+ final stored = persistence.storedMessages[0];
1197+ Assert.equals(chat.chatId, stored.chatId());
1198+ Assert.equals("bob@example.com", stored.to?.asString());
1199+ Assert.same(["bob@example.com", "carol@example.com"], stored.recipients.map(r -> r.asBare().asString()));
1200+ }
1201+ async.done();
1202+ return EventHandled;
1203+ });
1204+
1205+ final builder = new ChatMessageBuilder();
1206+ builder.text = "hello";
1207+ chat.sendMessage(builder, borogove.Chat.OutgoingE2EEPreference.NoE2EE);
1208+ }
1209+
1210+}
1211+
1212+@:access(borogove)
1213+class RecordingPersistence extends Dummy {
1214+ public var storedMessages: Array<borogove.ChatMessage> = [];
1215+
1216+ override public function storeMessages(accountId: String, messages: Array<borogove.ChatMessage>) {
1217+ storedMessages = storedMessages.concat(messages);
1218+ return Promise.resolve(messages);
1219+ }
11691220 }
11701221
11711222 @:access(borogove)
Back to top