diff --git a/packages/moxxmpp/lib/moxxmpp.dart b/packages/moxxmpp/lib/moxxmpp.dart index e44a60f..944b728 100644 --- a/packages/moxxmpp/lib/moxxmpp.dart +++ b/packages/moxxmpp/lib/moxxmpp.dart @@ -18,7 +18,6 @@ export 'package:moxxmpp/src/managers/namespaces.dart'; export 'package:moxxmpp/src/managers/priorities.dart'; export 'package:moxxmpp/src/message.dart'; export 'package:moxxmpp/src/namespaces.dart'; -export 'package:moxxmpp/src/negotiators/manager.dart'; export 'package:moxxmpp/src/negotiators/namespaces.dart'; export 'package:moxxmpp/src/negotiators/negotiator.dart'; export 'package:moxxmpp/src/ping.dart'; diff --git a/packages/moxxmpp/lib/src/namespaces.dart b/packages/moxxmpp/lib/src/namespaces.dart index eb98e63..d5bd41f 100644 --- a/packages/moxxmpp/lib/src/namespaces.dart +++ b/packages/moxxmpp/lib/src/namespaces.dart @@ -9,6 +9,7 @@ const fullStanzaXmlns = 'urn:ietf:params:xml:ns:xmpp-stanzas'; // RFC 6121 const rosterXmlns = 'jabber:iq:roster'; const rosterVersioningXmlns = 'urn:xmpp:features:rosterver'; +const subscriptionPreApprovalXmlns = 'urn:xmpp:features:pre-approval'; // XEP-0004 const dataFormsXmlns = 'jabber:x:data'; diff --git a/packages/moxxmpp/lib/src/negotiators/manager.dart b/packages/moxxmpp/lib/src/negotiators/manager.dart deleted file mode 100644 index 8b13789..0000000 --- a/packages/moxxmpp/lib/src/negotiators/manager.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/packages/moxxmpp/lib/src/negotiators/namespaces.dart b/packages/moxxmpp/lib/src/negotiators/namespaces.dart index 17691ec..e4f30d2 100644 --- a/packages/moxxmpp/lib/src/negotiators/namespaces.dart +++ b/packages/moxxmpp/lib/src/negotiators/namespaces.dart @@ -11,3 +11,4 @@ const sasl2Negotiator = 'org.moxxmpp.sasl.sasl2'; const bind2Negotiator = 'org.moxxmpp.bind2'; const saslFASTNegotiator = 'org.moxxmpp.sasl.fast'; const carbonsNegotiator = 'org.moxxmpp.bind2.carbons'; +const presenceNegotiator = 'org.moxxmpp.core.presence'; diff --git a/packages/moxxmpp/lib/src/presence.dart b/packages/moxxmpp/lib/src/presence.dart index e8fb407..db68ace 100644 --- a/packages/moxxmpp/lib/src/presence.dart +++ b/packages/moxxmpp/lib/src/presence.dart @@ -6,14 +6,44 @@ import 'package:moxxmpp/src/managers/data.dart'; import 'package:moxxmpp/src/managers/handlers.dart'; import 'package:moxxmpp/src/managers/namespaces.dart'; import 'package:moxxmpp/src/namespaces.dart'; +import 'package:moxxmpp/src/negotiators/namespaces.dart'; +import 'package:moxxmpp/src/negotiators/negotiator.dart'; import 'package:moxxmpp/src/stanza.dart'; import 'package:moxxmpp/src/stringxml.dart'; +import 'package:moxxmpp/src/types/result.dart'; /// A function that will be called when presence, outside of subscription request /// management, will be sent. Useful for managers that want to add [XMLNode]s to said /// presence. typedef PresencePreSendCallback = Future> Function(); +/// A pseudo-negotiator that does not really negotiate anything. Instead, its purpose +/// is to look for a stream feature indicating that we can pre-approve subscription +/// requests, shown by [PresenceNegotiator.preApprovalSupported]. +class PresenceNegotiator extends XmppFeatureNegotiatorBase { + PresenceNegotiator() + : super(11, false, subscriptionPreApprovalXmlns, presenceNegotiator); + + /// Flag indicating whether presence subscription pre-approval is supported + bool _supported = false; + bool get preApprovalSupported => _supported; + + @override + Future> negotiate( + XMLNode nonza, + ) async { + _supported = true; + return const Result(NegotiatorState.done); + } + + @override + void reset() { + _supported = false; + + super.reset(); + } +} + /// A mandatory manager that handles initial presence sending, sending of subscription /// request management requests and triggers events for incoming presence stanzas. class PresenceManager extends XmppManagerBase { diff --git a/packages/moxxmpp/test/xmpp_test.dart b/packages/moxxmpp/test/xmpp_test.dart index 21d80d0..d7fd9d8 100644 --- a/packages/moxxmpp/test/xmpp_test.dart +++ b/packages/moxxmpp/test/xmpp_test.dart @@ -794,4 +794,20 @@ void main() { expect(fakeSocket.getState(), 9); expect(await stanzaFuture != null, true); }); + + test('Test subscription pre-approval parsing', () async { + final rawFeatures = XMLNode.fromString( + ''' + + + + + + + + ''', + ); + + expect(PresenceNegotiator().matchesFeature(rawFeatures.children), true); + }); }