diff --git a/libdino/src/service/presence_manager.vala b/libdino/src/service/presence_manager.vala index e832687d..62100c2c 100644 --- a/libdino/src/service/presence_manager.vala +++ b/libdino/src/service/presence_manager.vala @@ -11,6 +11,7 @@ public class PresenceManager : StreamInteractionModule, Object { public signal void show_received(Show show, Jid jid, Account account); public signal void received_subscription_request(Jid jid, Account account); public signal void received_subscription_approval(Jid jid, Account account); + public signal void mutual_subscription(Jid jid, Account account); private StreamInteractor stream_interactor; private HashMap>> shows = new HashMap>>(Jid.hash_bare_func, Jid.equals_bare_func); @@ -98,6 +99,9 @@ public class PresenceManager : StreamInteractionModule, Object { stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).received_subscription_approval.connect((stream, jid) => { received_subscription_approval(jid, account); }); + stream_interactor.module_manager.get_module(account, Presence.Module.IDENTITY).mutual_subscription.connect((stream, jid) => { + mutual_subscription(jid, account); + }); } private void on_received_available_show(Account account, Jid jid, string show) { diff --git a/plugins/omemo/src/manager.vala b/plugins/omemo/src/manager.vala index 8654a4f5..7c8d8976 100644 --- a/plugins/omemo/src/manager.vala +++ b/plugins/omemo/src/manager.vala @@ -71,6 +71,7 @@ public class Manager : StreamInteractionModule, Object { stream_interactor.account_added.connect(on_account_added); stream_interactor.get_module(MessageProcessor.IDENTITY).received_pipeline.connect(received_message_listener); stream_interactor.get_module(MessageProcessor.IDENTITY).pre_message_send.connect(on_pre_message_send); + stream_interactor.get_module(PresenceManager.IDENTITY).mutual_subscription.connect(on_mutual_subscription); } private class ReceivedMessageListener : MessageListener { @@ -171,6 +172,13 @@ public class Manager : StreamInteractionModule, Object { } } + private void on_mutual_subscription(Jid jid, Account account) { + XmppStream? stream = stream_interactor.get_stream(account); + if(stream == null) return; + + stream_interactor.module_manager.get_module(account, StreamModule.IDENTITY).request_user_devicelist((!)stream, jid); + } + private void on_account_added(Account account) { stream_interactor.module_manager.get_module(account, StreamModule.IDENTITY).store_created.connect((store) => on_store_created(account, store)); stream_interactor.module_manager.get_module(account, StreamModule.IDENTITY).device_list_loaded.connect((jid, devices) => on_device_list_loaded(account, jid, devices)); @@ -341,7 +349,6 @@ public class Manager : StreamInteractionModule, Object { if (flag.has_room_feature(conversation.counterpart, Xep.Muc.Feature.NON_ANONYMOUS) && flag.has_room_feature(conversation.counterpart, Xep.Muc.Feature.MEMBERS_ONLY)) { foreach(Jid jid in stream_interactor.get_module(MucManager.IDENTITY).get_offline_members(conversation.counterpart, conversation.account)) { if (!trust_manager.is_known_address(conversation.account, jid.bare_jid)) { - module.request_user_devicelist(stream, jid.bare_jid); return false; } } @@ -349,11 +356,8 @@ public class Manager : StreamInteractionModule, Object { } else { return false; } - } else if (!trust_manager.is_known_address(conversation.account, conversation.counterpart.bare_jid)) { - module.request_user_devicelist(stream, conversation.counterpart.bare_jid); - return false; } - return true; + return trust_manager.is_known_address(conversation.account, conversation.counterpart.bare_jid); } public static void start(StreamInteractor stream_interactor, Database db) { diff --git a/xmpp-vala/src/module/presence/flag.vala b/xmpp-vala/src/module/presence/flag.vala index bb3562a4..77bc0b5f 100644 --- a/xmpp-vala/src/module/presence/flag.vala +++ b/xmpp-vala/src/module/presence/flag.vala @@ -57,4 +57,4 @@ public class Flag : XmppStreamFlag { } } -} \ No newline at end of file +} diff --git a/xmpp-vala/src/module/presence/module.vala b/xmpp-vala/src/module/presence/module.vala index 12b40245..2188d89d 100644 --- a/xmpp-vala/src/module/presence/module.vala +++ b/xmpp-vala/src/module/presence/module.vala @@ -1,3 +1,5 @@ +using Gee; + namespace Xmpp.Presence { private const string NS_URI = "jabber:client"; @@ -13,9 +15,13 @@ namespace Xmpp.Presence { public signal void received_subscription_request(XmppStream stream, Jid jid); public signal void received_subscription_approval(XmppStream stream, Jid jid); public signal void received_unsubscription(XmppStream stream, Jid jid); + public signal void mutual_subscription(XmppStream stream, Jid jid); public bool available_resource = true; + private Gee.List subscriptions = new ArrayList(Jid.equals_bare_func); + private Gee.List subscribers = new ArrayList(Jid.equals_bare_func); + public void request_subscription(XmppStream stream, Jid bare_jid) { Presence.Stanza presence = new Presence.Stanza(); presence.to = bare_jid; @@ -28,6 +34,8 @@ namespace Xmpp.Presence { presence.to = bare_jid; presence.type_ = Presence.Stanza.TYPE_SUBSCRIBED; send_presence(stream, presence); + subscribers.add(bare_jid); + if (subscriptions.contains(bare_jid)) mutual_subscription(stream, bare_jid); } public void deny_subscription(XmppStream stream, Jid bare_jid) { @@ -39,6 +47,7 @@ namespace Xmpp.Presence { presence.to = bare_jid; presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBED; send_presence(stream, presence); + subscribers.remove(bare_jid); } public void unsubscribe(XmppStream stream, Jid bare_jid) { @@ -46,6 +55,7 @@ namespace Xmpp.Presence { presence.to = bare_jid; presence.type_ = Presence.Stanza.TYPE_UNSUBSCRIBE; send_presence(stream, presence); + subscriptions.remove(bare_jid); } public void send_presence(XmppStream stream, Presence.Stanza presence) { @@ -82,10 +92,16 @@ namespace Xmpp.Presence { break; case Presence.Stanza.TYPE_SUBSCRIBED: received_subscription_approval(stream, presence.from); + subscriptions.add(presence.from); + if (subscribers.contains(presence.from)) mutual_subscription(stream, presence.from); break; case Presence.Stanza.TYPE_UNSUBSCRIBE: stream.get_flag(Flag.IDENTITY).remove_presence(presence.from); received_unsubscription(stream, presence.from); + subscribers.remove(presence.from); + break; + case Presence.Stanza.TYPE_UNSUBSCRIBED: + subscriptions.remove(presence.from); break; } }