git » sdk » commit 4813479

Handle roster push

author Stephen Paul Weber
2023-09-12 18:45:04 UTC
committer Stephen Paul Weber
2023-09-12 19:15:03 UTC
parent e199cea4fcb2154d130ff230c75080218e455b91

Handle roster push

Open a new chat for a new roster item, ignore removes for now.

xmpp/Client.hx +29 -0
xmpp/queries/RosterGet.hx +53 -0

diff --git a/xmpp/Client.hx b/xmpp/Client.hx
index 7ea1947..c9f885b 100644
--- a/xmpp/Client.hx
+++ b/xmpp/Client.hx
@@ -46,6 +46,35 @@ class Client extends xmpp.EventEmitter {
 			return EventUnhandled; // Allow others to get this event as well
 		});
 
+		this.stream.on("iq", function(event) {
+			final stanza:Stanza = event.stanza;
+			if (
+				stanza.attr.get("from") != null &&
+				stanza.attr.get("from") != JID.parse(jid).domain
+			) {
+				return EventUnhandled;
+			}
+
+			var roster = new RosterGet();
+			roster.handleResponse(stanza);
+			var items = roster.getResult();
+			if (items.length == 0) return EventUnhandled;
+
+			for (item in items) {
+				if (item.subscription != "remove") getDirectChat(item.jid, false);
+			}
+			this.trigger("chats/update", chats);
+
+			var reply = new Stanza("iq", {
+				type: "result",
+				id: stanza.attr.get("id"),
+				to: stanza.attr.get("from")
+			});
+			sendStanza(reply);
+
+			return EventHandled;
+		});
+
 		stream.sendStanza(new Stanza("presence")); // Set self to online
 		rosterGet();
 		return this.trigger("status/online", {});
diff --git a/xmpp/queries/RosterGet.hx b/xmpp/queries/RosterGet.hx
new file mode 100644
index 0000000..469e9d0
--- /dev/null
+++ b/xmpp/queries/RosterGet.hx
@@ -0,0 +1,53 @@
+package xmpp.queries;
+
+import haxe.DynamicAccess;
+import haxe.Exception;
+
+import xmpp.ID;
+import xmpp.ResultSet;
+import xmpp.Stanza;
+import xmpp.Stream;
+import xmpp.queries.GenericQuery;
+
+class RosterGet extends GenericQuery {
+	public var xmlns(default, null) = "jabber:iq:roster";
+	public var queryId:String = null;
+	public var ver:String = null;
+	private var responseStanza:Stanza;
+	private var result: Array<{ jid: String, fn: String, subscription: String }>;
+
+	public function new(?ver: String) {
+		var attr: DynamicAccess<String> = { xmlns: xmlns };
+		if (ver != null) attr["ver"] = ver;
+		/* Build basic query */
+		queryId = ID.short();
+		queryStanza = new Stanza("iq", { type: "get" })
+			.tag("query", attr)
+			.up();
+	}
+
+	public function handleResponse(stanza:Stanza) {
+		responseStanza = stanza;
+		finish();
+	}
+
+	public function getResult() {
+		if (responseStanza == null) {
+			return [];
+		}
+		if(result == null) {
+			var q = responseStanza.getChild("query", "jabber:iq:roster");
+			if(q == null) {
+				return [];
+			}
+			ver = q.attr.get("ver");
+			// TODO: cannot specify namespace here due to bugs in namespace handling in allTags
+			result = q.allTags("item").map((item) -> {
+				jid: item.attr.get("jid"),
+				fn: item.attr.get("name"),
+				subscription: item.attr.get("subscription")
+			});
+		}
+		return result;
+	}
+}