diff --git a/plugins/omemo/src/protocol/stream_module.vala b/plugins/omemo/src/protocol/stream_module.vala index fdfca30c..21476bd8 100644 --- a/plugins/omemo/src/protocol/stream_module.vala +++ b/plugins/omemo/src/protocol/stream_module.vala @@ -75,7 +75,7 @@ public class StreamModule : XmppStreamModule { if (!am_on_devicelist) { debug("Not on device list, adding id"); node.put_node(new StanzaNode.build("device", NS_URI).put_attribute("id", store.local_registration_id.to_string())); - stream.get_module(Pubsub.Module.IDENTITY).publish.begin(stream, jid, NODE_DEVICELIST, id, node, Xmpp.Xep.Pubsub.ACCESS_MODEL_OPEN); + stream.get_module(Pubsub.Module.IDENTITY).publish.begin(stream, jid, NODE_DEVICELIST, id, node); } publish_bundles_if_needed(stream, jid); } @@ -254,7 +254,7 @@ public class StreamModule : XmppStreamModule { } if (changed) { - publish_bundles(stream, (!)signed_pre_key_record, identity_key_pair, pre_key_records, (int32) store.local_registration_id); + publish_bundles.begin(stream, (!)signed_pre_key_record, identity_key_pair, pre_key_records, (int32) store.local_registration_id); } } catch (Error e) { warning(@"Unexpected error while publishing bundle: $(e.message)\n"); @@ -262,7 +262,7 @@ public class StreamModule : XmppStreamModule { stream.get_module(IDENTITY).active_bundle_requests.remove(jid.bare_jid.to_string() + @":$(store.local_registration_id)"); } - public static void publish_bundles(XmppStream stream, SignedPreKeyRecord signed_pre_key_record, IdentityKeyPair identity_key_pair, Set pre_key_records, int32 device_id) throws Error { + public async void publish_bundles(XmppStream stream, SignedPreKeyRecord signed_pre_key_record, IdentityKeyPair identity_key_pair, Set pre_key_records, int32 device_id) throws Error { ECKeyPair tmp; StanzaNode bundle = new StanzaNode.build("bundle", NS_URI) .add_self_xmlns() @@ -281,7 +281,22 @@ public class StreamModule : XmppStreamModule { } bundle.put_node(prekeys); - stream.get_module(Pubsub.Module.IDENTITY).publish.begin(stream, null, @"$NODE_BUNDLES:$device_id", "1", bundle, Xmpp.Xep.Pubsub.ACCESS_MODEL_OPEN); + yield stream.get_module(Pubsub.Module.IDENTITY).publish(stream, null, @"$NODE_BUNDLES:$device_id", "1", bundle); + yield try_make_bundle_public(stream, device_id); + + } + + private async void try_make_bundle_public(XmppStream stream, int32 device_id) { + DataForms.DataForm? data_form = yield stream.get_module(Pubsub.Module.IDENTITY).request_node_config(stream, null, @"$NODE_BUNDLES:$device_id"); + if (data_form == null) return; + + foreach (DataForms.DataForm.Field field in data_form.fields) { + if (field.var == "pubsub#access_model" && field.get_value_string() != Pubsub.ACCESS_MODEL_OPEN) { + field.set_value_string(Pubsub.ACCESS_MODEL_OPEN); + yield stream.get_module(Pubsub.Module.IDENTITY).submit_node_config(stream, data_form, @"$NODE_BUNDLES:$device_id"); + break; + } + } } public override string get_ns() { diff --git a/xmpp-vala/src/module/iq/module.vala b/xmpp-vala/src/module/iq/module.vala index f5cb6acf..51a5f359 100644 --- a/xmpp-vala/src/module/iq/module.vala +++ b/xmpp-vala/src/module/iq/module.vala @@ -9,6 +9,16 @@ namespace Xmpp.Iq { private HashMap responseListeners = new HashMap(); private HashMap> namespaceRegistrants = new HashMap>(); + public async Iq.Stanza send_iq_async(XmppStream stream, Iq.Stanza iq) { + Iq.Stanza? return_stanza = null; + send_iq(stream, iq, (_, result_iq) => { + return_stanza = result_iq; + Idle.add(send_iq_async.callback); + }); + yield; + return return_stanza; + } + public delegate void OnResult(XmppStream stream, Iq.Stanza iq); public void send_iq(XmppStream stream, Iq.Stanza iq, owned OnResult? listener = null) { stream.write(iq.stanza); diff --git a/xmpp-vala/src/module/xep/0004_data_forms.vala b/xmpp-vala/src/module/xep/0004_data_forms.vala index 1c04d81e..52275bc5 100644 --- a/xmpp-vala/src/module/xep/0004_data_forms.vala +++ b/xmpp-vala/src/module/xep/0004_data_forms.vala @@ -83,7 +83,7 @@ public class DataForm { return values.size > 0 ? values[0] : ""; } - internal void set_value_string(string val) { + public void set_value_string(string val) { StanzaNode? value_node = node.get_subnode("value", NS_URI); if (value_node == null) { value_node = new StanzaNode.build("value", NS_URI); diff --git a/xmpp-vala/src/module/xep/0060_pubsub.vala b/xmpp-vala/src/module/xep/0060_pubsub.vala index 9493c5f9..21daca82 100644 --- a/xmpp-vala/src/module/xep/0060_pubsub.vala +++ b/xmpp-vala/src/module/xep/0060_pubsub.vala @@ -60,7 +60,7 @@ namespace Xmpp.Xep.Pubsub { }); } - public async bool publish(XmppStream stream, Jid? jid, string node_id, string? item_id, StanzaNode content, string? access_model=null, int? max_items = null) { + public async bool publish(XmppStream stream, Jid? jid, string node_id, string? item_id, StanzaNode content, string? access_model=null) { StanzaNode pubsub_node = new StanzaNode.build("pubsub", NS_URI).add_self_xmlns(); StanzaNode publish_node = new StanzaNode.build("publish", NS_URI).put_attribute("node", node_id); pubsub_node.put_node(publish_node); @@ -69,7 +69,7 @@ namespace Xmpp.Xep.Pubsub { items_node.put_node(content); publish_node.put_node(items_node); - if (access_model != null || max_items != null) { + if (access_model != null) { StanzaNode publish_options_node = new StanzaNode.build("publish-options", NS_URI); pubsub_node.put_node(publish_options_node); @@ -82,11 +82,6 @@ namespace Xmpp.Xep.Pubsub { field.set_value_string(access_model); data_form.add_field(field); } - if (max_items != null) { - DataForms.DataForm.Field field = new DataForms.DataForm.Field() { var="pubsub#max_items" }; - field.set_value_string(max_items.to_string()); - data_form.add_field(field); - } publish_options_node.put_node(data_form.get_submit_node()); } @@ -126,6 +121,31 @@ namespace Xmpp.Xep.Pubsub { stream.get_module(Iq.Module.IDENTITY).send_iq(stream, iq, null); } + public async DataForms.DataForm? request_node_config(XmppStream stream, Jid? jid, string node_id) { + StanzaNode pubsub_node = new StanzaNode.build("pubsub", NS_URI_OWNER).add_self_xmlns(); + StanzaNode publish_node = new StanzaNode.build("configure", NS_URI_OWNER).put_attribute("node", node_id); + pubsub_node.put_node(publish_node); + + Iq.Stanza iq = new Iq.Stanza.get(pubsub_node); + Iq.Stanza result_iq = yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq); + StanzaNode? data_form_node = result_iq.stanza.get_deep_subnode(Pubsub.NS_URI_OWNER + ":pubsub", Pubsub.NS_URI_OWNER + ":configure", "jabber:x:data:x"); + if (data_form_node == null) return null; + return DataForms.DataForm.create_from_node(stream, data_form_node, () => {}); + } + + public async void submit_node_config(XmppStream stream, DataForms.DataForm data_form, string node_id) { + StanzaNode submit_node = data_form.get_submit_node(); + + StanzaNode pubsub_node = new StanzaNode.build("pubsub", Pubsub.NS_URI_OWNER).add_self_xmlns(); + StanzaNode publish_node = new StanzaNode.build("configure", Pubsub.NS_URI_OWNER).put_attribute("node", node_id); + pubsub_node.put_node(publish_node); + publish_node.put_node(submit_node); + + + Iq.Stanza iq = new Iq.Stanza.set(pubsub_node); + yield stream.get_module(Iq.Module.IDENTITY).send_iq_async(stream, iq); + } + public override void attach(XmppStream stream) { stream.get_module(MessageModule.IDENTITY).received_message.connect(on_received_message); } diff --git a/xmpp-vala/src/module/xep/0402_bookmarks2.vala b/xmpp-vala/src/module/xep/0402_bookmarks2.vala index 8394580f..15386398 100644 --- a/xmpp-vala/src/module/xep/0402_bookmarks2.vala +++ b/xmpp-vala/src/module/xep/0402_bookmarks2.vala @@ -42,7 +42,7 @@ public class Module : BookmarksProvider, XmppStreamModule { if (conference.nick != null) { conference_node.put_node((new StanzaNode.build("nick", NS_URI)).put_node(new StanzaNode.text(conference.nick))); } - yield stream.get_module(Pubsub.Module.IDENTITY).publish(stream, stream.get_flag(Bind.Flag.IDENTITY).my_jid.bare_jid, NS_URI, conference.jid.to_string(), conference_node, Xmpp.Xep.Pubsub.ACCESS_MODEL_WHITELIST, 128); + yield stream.get_module(Pubsub.Module.IDENTITY).publish(stream, stream.get_flag(Bind.Flag.IDENTITY).my_jid.bare_jid, NS_URI, conference.jid.to_string(), conference_node, Xmpp.Xep.Pubsub.ACCESS_MODEL_WHITELIST); } public async void replace_conference(XmppStream stream, Conference orig_conference, Conference modified_conference) {