feat(all): Migrate to the new StanzaDetails API
This commit is contained in:
		
							parent
							
								
									bd4e1d28ea
								
							
						
					
					
						commit
						3163101f82
					
				
							
								
								
									
										2
									
								
								.gitlint
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								.gitlint
									
									
									
									
									
								
							@ -7,7 +7,7 @@ line-length=72
 | 
			
		||||
[title-trailing-punctuation]
 | 
			
		||||
[title-hard-tab]
 | 
			
		||||
[title-match-regex]
 | 
			
		||||
regex=^((feat|fix|chore|refactor|docs|release|test)\((meta|tests|style|docs|xep|core|example)+(,(meta|tests|style|docs|xep|core|example))*\)|release): [A-Z0-9].*$
 | 
			
		||||
regex=^((feat|fix|chore|refactor|docs|release|test)\((meta|tests|style|docs|xep|core|example|all)+(,(meta|tests|style|docs|xep|core|example|all))*\)|release): [A-Z0-9].*$
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
[body-trailing-whitespace]
 | 
			
		||||
 | 
			
		||||
@ -9,6 +9,8 @@
 | 
			
		||||
- **BREAKING**: Remove `DiscoManager.discoInfoCapHashQuery`.
 | 
			
		||||
- **BREAKING**: The entity argument of `DiscoManager.discoInfoQuery` and `DiscoManager.discoItemsQuery` are now `JID` instead of `String`.
 | 
			
		||||
- **BREAKING**: `PubSubManager` and `UserAvatarManager` now use `JID` instead of `String`.
 | 
			
		||||
- **BREAKING**: `XmppConnection.sendStanza` not only takes a `StanzaDetails` argument.
 | 
			
		||||
- Sent stanzas are not kept in a queue until sent.
 | 
			
		||||
 | 
			
		||||
## 0.3.1
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -420,12 +420,17 @@ class XmppConnection {
 | 
			
		||||
        .contains(await getConnectionState());
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<Future<XMLNode>?> sendStanza2(StanzaDetails details) async {
 | 
			
		||||
  /// Sends a stanza described by [details] to the server. Until sent, the stanza is
 | 
			
		||||
  /// kept in a queue, that is flushed after going online again. If Stream Management
 | 
			
		||||
  /// is active, stanza's acknowledgement is tracked.
 | 
			
		||||
  // TODO(Unknown): if addId = false, the function crashes.
 | 
			
		||||
  Future<XMLNode?> sendStanza(StanzaDetails details) async {
 | 
			
		||||
    assert(
 | 
			
		||||
      implies(
 | 
			
		||||
          details.awaitable,
 | 
			
		||||
          details.stanza.id != null && details.stanza.id!.isNotEmpty ||
 | 
			
		||||
              details.addId),
 | 
			
		||||
        details.awaitable,
 | 
			
		||||
        details.stanza.id != null && details.stanza.id!.isNotEmpty ||
 | 
			
		||||
            details.addId,
 | 
			
		||||
      ),
 | 
			
		||||
      'An awaitable stanza must have an id',
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
@ -550,131 +555,6 @@ class XmppConnection {
 | 
			
		||||
    _log.fine('Done');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Sends a [stanza] to the server. If stream management is enabled, then keeping track
 | 
			
		||||
  /// of the stanza is taken care of. Returns a Future that resolves when we receive a
 | 
			
		||||
  /// response to the stanza.
 | 
			
		||||
  ///
 | 
			
		||||
  /// If addFrom is true, then a 'from' attribute will be added to the stanza if
 | 
			
		||||
  /// [stanza] has none.
 | 
			
		||||
  /// If addId is true, then an 'id' attribute will be added to the stanza if [stanza] has
 | 
			
		||||
  /// none.
 | 
			
		||||
  // TODO(Unknown): if addId = false, the function crashes.
 | 
			
		||||
  Future<XMLNode> sendStanza(
 | 
			
		||||
    Stanza stanza, {
 | 
			
		||||
    StanzaFromType addFrom = StanzaFromType.full,
 | 
			
		||||
    bool addId = true,
 | 
			
		||||
    bool awaitable = true,
 | 
			
		||||
    bool encrypted = false,
 | 
			
		||||
    bool forceEncryption = false,
 | 
			
		||||
  }) async {
 | 
			
		||||
    assert(
 | 
			
		||||
      implies(addId == false && stanza.id == null, !awaitable),
 | 
			
		||||
      'Cannot await a stanza with no id',
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Add extra data in case it was not set
 | 
			
		||||
    var stanza_ = stanza;
 | 
			
		||||
    if (addId && (stanza_.id == null || stanza_.id == '')) {
 | 
			
		||||
      stanza_ = stanza.copyWith(id: generateId());
 | 
			
		||||
    }
 | 
			
		||||
    if (addFrom != StanzaFromType.none &&
 | 
			
		||||
        (stanza_.from == null || stanza_.from == '')) {
 | 
			
		||||
      switch (addFrom) {
 | 
			
		||||
        case StanzaFromType.full:
 | 
			
		||||
          {
 | 
			
		||||
            stanza_ = stanza_.copyWith(
 | 
			
		||||
              from: _getJidWithResource().toString(),
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
        case StanzaFromType.bare:
 | 
			
		||||
          {
 | 
			
		||||
            stanza_ = stanza_.copyWith(
 | 
			
		||||
              from: connectionSettings.jid.toBare().toString(),
 | 
			
		||||
            );
 | 
			
		||||
          }
 | 
			
		||||
          break;
 | 
			
		||||
        case StanzaFromType.none:
 | 
			
		||||
          break;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    stanza_ = stanza_.copyWith(
 | 
			
		||||
      xmlns: _negotiationsHandler.getStanzaNamespace(),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    _log.fine('Running pre stanza handlers..');
 | 
			
		||||
    final data = await _runOutgoingPreStanzaHandlers(
 | 
			
		||||
      stanza_,
 | 
			
		||||
      initial: StanzaHandlerData(
 | 
			
		||||
        false,
 | 
			
		||||
        false,
 | 
			
		||||
        null,
 | 
			
		||||
        stanza_,
 | 
			
		||||
        encrypted: encrypted,
 | 
			
		||||
        forceEncryption: forceEncryption,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    _log.fine('Done');
 | 
			
		||||
 | 
			
		||||
    if (data.cancel) {
 | 
			
		||||
      _log.fine('A stanza handler indicated that it wants to cancel sending.');
 | 
			
		||||
      await _sendEvent(StanzaSendingCancelledEvent(data));
 | 
			
		||||
      return Stanza(
 | 
			
		||||
        tag: data.stanza.tag,
 | 
			
		||||
        to: data.stanza.from,
 | 
			
		||||
        from: data.stanza.to,
 | 
			
		||||
        attributes: <String, String>{
 | 
			
		||||
          'type': 'error',
 | 
			
		||||
          if (data.stanza.id != null) 'id': data.stanza.id!,
 | 
			
		||||
        },
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final prefix = data.encrypted ? '(Encrypted) ' : '';
 | 
			
		||||
    _log.finest('==> $prefix${stanza_.toXml()}');
 | 
			
		||||
 | 
			
		||||
    final stanzaString = data.stanza.toXml();
 | 
			
		||||
 | 
			
		||||
    // ignore: cascade_invocations
 | 
			
		||||
    _log.fine('Attempting to acquire lock for ${data.stanza.id}...');
 | 
			
		||||
    // TODO(PapaTutuWawa): Handle this much more graceful
 | 
			
		||||
    var future = Future.value(XMLNode(tag: 'not-used'));
 | 
			
		||||
    if (awaitable) {
 | 
			
		||||
      future = await _stanzaAwaiter.addPending(
 | 
			
		||||
        // A stanza with no to attribute is for direct processing by the server. As such,
 | 
			
		||||
        // we can correlate it by just *assuming* we have that attribute
 | 
			
		||||
        // (RFC 6120 Section 8.1.1.1)
 | 
			
		||||
        data.stanza.to ?? connectionSettings.jid.toBare().toString(),
 | 
			
		||||
        data.stanza.id!,
 | 
			
		||||
        data.stanza.tag,
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // This uses the StreamManager to behave like a send queue
 | 
			
		||||
    if (await _canSendData()) {
 | 
			
		||||
      _socket.write(stanzaString);
 | 
			
		||||
 | 
			
		||||
      // Try to ack every stanza
 | 
			
		||||
      // NOTE: Here we have send an Ack request nonza. This is now done by StreamManagementManager when receiving the StanzaSentEvent
 | 
			
		||||
    } else {
 | 
			
		||||
      _log.fine('_canSendData() returned false.');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    _log.fine('Running post stanza handlers..');
 | 
			
		||||
    await _runOutgoingPostStanzaHandlers(
 | 
			
		||||
      stanza_,
 | 
			
		||||
      initial: StanzaHandlerData(
 | 
			
		||||
        false,
 | 
			
		||||
        false,
 | 
			
		||||
        null,
 | 
			
		||||
        stanza_,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    _log.fine('Done');
 | 
			
		||||
 | 
			
		||||
    return future;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Called when we timeout during connecting
 | 
			
		||||
  Future<void> _onConnectingTimeout() async {
 | 
			
		||||
    _log.severe('Connection stuck in "connecting". Causing a reconnection...');
 | 
			
		||||
@ -696,18 +576,11 @@ class XmppConnection {
 | 
			
		||||
    // Set the new routing state
 | 
			
		||||
    _updateRoutingState(RoutingState.handleStanzas);
 | 
			
		||||
 | 
			
		||||
    // Set the connection state
 | 
			
		||||
    await _setConnectionState(XmppConnectionState.connected);
 | 
			
		||||
 | 
			
		||||
    // Enable reconnections
 | 
			
		||||
    if (_enableReconnectOnSuccess) {
 | 
			
		||||
      await _reconnectionPolicy.setShouldReconnect(true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Resolve the connection completion future
 | 
			
		||||
    _connectionCompleter?.complete(const Result(true));
 | 
			
		||||
    _connectionCompleter = null;
 | 
			
		||||
 | 
			
		||||
    // Tell consumers of the event stream that we're done with stream feature
 | 
			
		||||
    // negotiations
 | 
			
		||||
    await _sendEvent(
 | 
			
		||||
@ -716,6 +589,16 @@ class XmppConnection {
 | 
			
		||||
            false,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    // Set the connection state
 | 
			
		||||
    await _setConnectionState(XmppConnectionState.connected);
 | 
			
		||||
 | 
			
		||||
    // Resolve the connection completion future
 | 
			
		||||
    _connectionCompleter?.complete(const Result(true));
 | 
			
		||||
    _connectionCompleter = null;
 | 
			
		||||
 | 
			
		||||
    // Flush the stanza send queue
 | 
			
		||||
    await _stanzaQueue.restart();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Sets the connection state to [state] and triggers an event of type
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,7 @@
 | 
			
		||||
import 'package:moxxmpp/src/connection.dart';
 | 
			
		||||
import 'package:moxxmpp/src/managers/data.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
 | 
			
		||||
/// Bounce a stanza if it was not handled by any manager. [conn] is the connection object
 | 
			
		||||
/// to use for sending the stanza. [data] is the StanzaHandlerData of the unhandled
 | 
			
		||||
@ -23,9 +24,11 @@ Future<void> handleUnhandledStanza(
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    await conn.sendStanza(
 | 
			
		||||
      stanza,
 | 
			
		||||
      awaitable: false,
 | 
			
		||||
      forceEncryption: data.encrypted,
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        stanza,
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
        forceEncryption: data.encrypted,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -6,8 +6,8 @@ import 'package:moxxmpp/src/managers/base.dart';
 | 
			
		||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
 | 
			
		||||
import 'package:moxxmpp/src/settings.dart';
 | 
			
		||||
import 'package:moxxmpp/src/socket.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
 | 
			
		||||
class XmppManagerAttributes {
 | 
			
		||||
  XmppManagerAttributes({
 | 
			
		||||
@ -23,14 +23,7 @@ class XmppManagerAttributes {
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  /// Send a stanza whose response can be awaited.
 | 
			
		||||
  final Future<XMLNode> Function(
 | 
			
		||||
    Stanza stanza, {
 | 
			
		||||
    StanzaFromType addFrom,
 | 
			
		||||
    bool addId,
 | 
			
		||||
    bool awaitable,
 | 
			
		||||
    bool encrypted,
 | 
			
		||||
    bool forceEncryption,
 | 
			
		||||
  }) sendStanza;
 | 
			
		||||
  final Future<XMLNode?> Function(StanzaDetails) sendStanza;
 | 
			
		||||
 | 
			
		||||
  /// Send a nonza.
 | 
			
		||||
  final void Function(XMLNode) sendNonza;
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ 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/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/errors.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/types.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
 | 
			
		||||
@ -165,9 +166,11 @@ abstract class XmppManagerBase {
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    await getAttributes().sendStanza(
 | 
			
		||||
      stanza,
 | 
			
		||||
      awaitable: false,
 | 
			
		||||
      forceEncryption: data.encrypted,
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        stanza,
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
        forceEncryption: data.encrypted,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ import 'package:moxxmpp/src/managers/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/staging/file_upload_notification.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0066.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0085.dart';
 | 
			
		||||
@ -320,6 +321,11 @@ class MessageManager extends XmppManagerBase {
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    getAttributes().sendStanza(stanza, awaitable: false);
 | 
			
		||||
    getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        stanza,
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -7,10 +7,9 @@ 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/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0198/negotiator.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.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
 | 
			
		||||
@ -49,12 +48,8 @@ class PresenceManager extends XmppManagerBase {
 | 
			
		||||
  Future<void> onXmppEvent(XmppEvent event) async {
 | 
			
		||||
    if (event is StreamNegotiationsDoneEvent) {
 | 
			
		||||
      // Send initial presence only when we have not resumed the stream
 | 
			
		||||
      final sm = getAttributes().getNegotiatorById<StreamManagementNegotiator>(
 | 
			
		||||
        streamManagementNegotiator,
 | 
			
		||||
      );
 | 
			
		||||
      final isResumed = sm?.isResumed ?? false;
 | 
			
		||||
      if (!isResumed) {
 | 
			
		||||
        unawaited(sendInitialPresence());
 | 
			
		||||
      if (!event.resumed) {
 | 
			
		||||
        await sendInitialPresence();
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -108,66 +103,82 @@ class PresenceManager extends XmppManagerBase {
 | 
			
		||||
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    await attrs.sendStanza(
 | 
			
		||||
      Stanza.presence(
 | 
			
		||||
        from: attrs.getFullJID().toString(),
 | 
			
		||||
        children: children,
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.presence(
 | 
			
		||||
          from: attrs.getFullJID().toString(),
 | 
			
		||||
          children: children,
 | 
			
		||||
        ),
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
        addId: false,
 | 
			
		||||
      ),
 | 
			
		||||
      awaitable: false,
 | 
			
		||||
      addId: false,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Send an unavailable presence with no 'to' attribute.
 | 
			
		||||
  void sendUnavailablePresence() {
 | 
			
		||||
    getAttributes().sendStanza(
 | 
			
		||||
      Stanza.presence(
 | 
			
		||||
        type: 'unavailable',
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.presence(
 | 
			
		||||
          type: 'unavailable',
 | 
			
		||||
        ),
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
      ),
 | 
			
		||||
      addFrom: StanzaFromType.full,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Sends a subscription request to [to].
 | 
			
		||||
  void sendSubscriptionRequest(String to) {
 | 
			
		||||
    getAttributes().sendStanza(
 | 
			
		||||
      Stanza.presence(
 | 
			
		||||
        type: 'subscribe',
 | 
			
		||||
        to: to,
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.presence(
 | 
			
		||||
          type: 'subscribe',
 | 
			
		||||
          to: to,
 | 
			
		||||
        ),
 | 
			
		||||
        addFrom: StanzaFromType.none,
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
      ),
 | 
			
		||||
      addFrom: StanzaFromType.none,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Sends an unsubscription request to [to].
 | 
			
		||||
  void sendUnsubscriptionRequest(String to) {
 | 
			
		||||
    getAttributes().sendStanza(
 | 
			
		||||
      Stanza.presence(
 | 
			
		||||
        type: 'unsubscribe',
 | 
			
		||||
        to: to,
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.presence(
 | 
			
		||||
          type: 'unsubscribe',
 | 
			
		||||
          to: to,
 | 
			
		||||
        ),
 | 
			
		||||
        addFrom: StanzaFromType.none,
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
      ),
 | 
			
		||||
      addFrom: StanzaFromType.none,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Accept a presence subscription request for [to].
 | 
			
		||||
  void sendSubscriptionRequestApproval(String to) {
 | 
			
		||||
    getAttributes().sendStanza(
 | 
			
		||||
      Stanza.presence(
 | 
			
		||||
        type: 'subscribed',
 | 
			
		||||
        to: to,
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.presence(
 | 
			
		||||
          type: 'subscribed',
 | 
			
		||||
          to: to,
 | 
			
		||||
        ),
 | 
			
		||||
        addFrom: StanzaFromType.none,
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
      ),
 | 
			
		||||
      addFrom: StanzaFromType.none,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /// Reject a presence subscription request for [to].
 | 
			
		||||
  void sendSubscriptionRequestRejection(String to) {
 | 
			
		||||
    getAttributes().sendStanza(
 | 
			
		||||
      Stanza.presence(
 | 
			
		||||
        type: 'unsubscribed',
 | 
			
		||||
        to: to,
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.presence(
 | 
			
		||||
          type: 'unsubscribed',
 | 
			
		||||
          to: to,
 | 
			
		||||
        ),
 | 
			
		||||
        addFrom: StanzaFromType.none,
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
      ),
 | 
			
		||||
      addFrom: StanzaFromType.none,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -15,6 +15,7 @@ import 'package:moxxmpp/src/roster/state.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/types/result.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
 | 
			
		||||
@immutable
 | 
			
		||||
class XmppRosterItem {
 | 
			
		||||
@ -235,14 +236,16 @@ class RosterManager extends XmppManagerBase {
 | 
			
		||||
      query.attributes['ver'] = rosterVersion;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final response = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        children: [
 | 
			
		||||
          query,
 | 
			
		||||
        ],
 | 
			
		||||
    final response = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          children: [
 | 
			
		||||
            query,
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (response.attributes['type'] != 'result') {
 | 
			
		||||
      logger.warning('Error requesting roster: ${response.toXml()}');
 | 
			
		||||
@ -258,20 +261,22 @@ class RosterManager extends XmppManagerBase {
 | 
			
		||||
  Future<Result<RosterRequestResult?, RosterError>>
 | 
			
		||||
      requestRosterPushes() async {
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    final result = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'query',
 | 
			
		||||
            xmlns: rosterXmlns,
 | 
			
		||||
            attributes: {
 | 
			
		||||
              'ver': await _stateManager.getRosterVersion() ?? '',
 | 
			
		||||
            },
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'query',
 | 
			
		||||
              xmlns: rosterXmlns,
 | 
			
		||||
              attributes: {
 | 
			
		||||
                'ver': await _stateManager.getRosterVersion() ?? '',
 | 
			
		||||
              },
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      logger.warning('Requesting roster pushes failed: ${result.toXml()}');
 | 
			
		||||
@ -296,31 +301,33 @@ class RosterManager extends XmppManagerBase {
 | 
			
		||||
    List<String>? groups,
 | 
			
		||||
  }) async {
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    final response = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'query',
 | 
			
		||||
            xmlns: rosterXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'item',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'jid': jid,
 | 
			
		||||
                  ...title == jid.split('@')[0]
 | 
			
		||||
                      ? <String, String>{}
 | 
			
		||||
                      : <String, String>{'name': title}
 | 
			
		||||
                },
 | 
			
		||||
                children: (groups ?? [])
 | 
			
		||||
                    .map((group) => XMLNode(tag: 'group', text: group))
 | 
			
		||||
                    .toList(),
 | 
			
		||||
              )
 | 
			
		||||
            ],
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final response = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'query',
 | 
			
		||||
              xmlns: rosterXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'item',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'jid': jid,
 | 
			
		||||
                    ...title == jid.split('@')[0]
 | 
			
		||||
                        ? <String, String>{}
 | 
			
		||||
                        : <String, String>{'name': title}
 | 
			
		||||
                  },
 | 
			
		||||
                  children: (groups ?? [])
 | 
			
		||||
                      .map((group) => XMLNode(tag: 'group', text: group))
 | 
			
		||||
                      .toList(),
 | 
			
		||||
                )
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (response.attributes['type'] != 'result') {
 | 
			
		||||
      logger.severe('Error adding $jid to roster: $response');
 | 
			
		||||
@ -334,26 +341,28 @@ class RosterManager extends XmppManagerBase {
 | 
			
		||||
  /// false otherwise.
 | 
			
		||||
  Future<RosterRemovalResult> removeFromRoster(String jid) async {
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    final response = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'query',
 | 
			
		||||
            xmlns: rosterXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'item',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'jid': jid,
 | 
			
		||||
                  'subscription': 'remove'
 | 
			
		||||
                },
 | 
			
		||||
              )
 | 
			
		||||
            ],
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final response = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'query',
 | 
			
		||||
              xmlns: rosterXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'item',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'jid': jid,
 | 
			
		||||
                    'subscription': 'remove'
 | 
			
		||||
                  },
 | 
			
		||||
                )
 | 
			
		||||
              ],
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (response.attributes['type'] != 'result') {
 | 
			
		||||
      logger.severe('Failed to remove roster item: ${response.toXml()}');
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/types/result.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/wait.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/cache.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/errors.dart';
 | 
			
		||||
@ -291,10 +292,12 @@ class DiscoManager extends XmppManagerBase {
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final stanza = await getAttributes().sendStanza(
 | 
			
		||||
      buildDiscoInfoQueryStanza(entity, node),
 | 
			
		||||
      encrypted: !shouldEncrypt,
 | 
			
		||||
    );
 | 
			
		||||
    final stanza = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        buildDiscoInfoQueryStanza(entity, node),
 | 
			
		||||
        encrypted: !shouldEncrypt,
 | 
			
		||||
      ),
 | 
			
		||||
    ))!;
 | 
			
		||||
    final query = stanza.firstTag('query');
 | 
			
		||||
    if (query == null) {
 | 
			
		||||
      final result = Result<DiscoError, DiscoInfo>(InvalidResponseDiscoError());
 | 
			
		||||
@ -331,10 +334,12 @@ class DiscoManager extends XmppManagerBase {
 | 
			
		||||
      return future;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final stanza = await getAttributes().sendStanza(
 | 
			
		||||
      buildDiscoItemsQueryStanza(entity, node: node),
 | 
			
		||||
      encrypted: !shouldEncrypt,
 | 
			
		||||
    ) as Stanza;
 | 
			
		||||
    final stanza = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        buildDiscoItemsQueryStanza(entity, node: node),
 | 
			
		||||
        encrypted: !shouldEncrypt,
 | 
			
		||||
      ),
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    final query = stanza.firstTag('query');
 | 
			
		||||
    if (query == null) {
 | 
			
		||||
@ -344,7 +349,7 @@ class DiscoManager extends XmppManagerBase {
 | 
			
		||||
      return result;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (stanza.type == 'error') {
 | 
			
		||||
    if (stanza.attributes['type'] == 'error') {
 | 
			
		||||
      //final error = stanza.firstTag('error');
 | 
			
		||||
      //print("Disco Items error: " + error.toXml());
 | 
			
		||||
      final result =
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/types/result.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
 | 
			
		||||
abstract class VCardError {}
 | 
			
		||||
 | 
			
		||||
@ -103,19 +104,21 @@ class VCardManager extends XmppManagerBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<Result<VCardError, VCard>> requestVCard(String jid) async {
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        to: jid,
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'vCard',
 | 
			
		||||
            xmlns: vCardTempXmlns,
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          to: jid,
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'vCard',
 | 
			
		||||
              xmlns: vCardTempXmlns,
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
        encrypted: true,
 | 
			
		||||
      ),
 | 
			
		||||
      encrypted: true,
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      return Result(UnknownVCardError());
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/types/result.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0004.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/errors.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/types.dart';
 | 
			
		||||
@ -181,27 +182,29 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
 | 
			
		||||
  Future<Result<PubSubError, bool>> subscribe(String jid, String node) async {
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    final result = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        to: jid,
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'subscribe',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'node': node,
 | 
			
		||||
                  'jid': attrs.getFullJID().toBare().toString(),
 | 
			
		||||
                },
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          to: jid,
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'subscribe',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'node': node,
 | 
			
		||||
                    'jid': attrs.getFullJID().toBare().toString(),
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      return Result(UnknownPubSubError());
 | 
			
		||||
@ -222,27 +225,29 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
 | 
			
		||||
  Future<Result<PubSubError, bool>> unsubscribe(String jid, String node) async {
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    final result = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        to: jid,
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'unsubscribe',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'node': node,
 | 
			
		||||
                  'jid': attrs.getFullJID().toBare().toString(),
 | 
			
		||||
                },
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          to: jid,
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'unsubscribe',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'node': node,
 | 
			
		||||
                    'jid': attrs.getFullJID().toBare().toString(),
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      return Result(UnknownPubSubError());
 | 
			
		||||
@ -293,38 +298,40 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
      pubOptions = await preprocessPublishOptions(jid, node, options);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        to: jid.toString(),
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'publish',
 | 
			
		||||
                attributes: <String, String>{'node': node},
 | 
			
		||||
                children: [
 | 
			
		||||
                  XMLNode(
 | 
			
		||||
                    tag: 'item',
 | 
			
		||||
                    attributes: id != null
 | 
			
		||||
                        ? <String, String>{'id': id}
 | 
			
		||||
                        : <String, String>{},
 | 
			
		||||
                    children: [payload],
 | 
			
		||||
                  )
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
              if (pubOptions != null)
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          to: jid.toString(),
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'publish-options',
 | 
			
		||||
                  children: [pubOptions.toXml()],
 | 
			
		||||
                  tag: 'publish',
 | 
			
		||||
                  attributes: <String, String>{'node': node},
 | 
			
		||||
                  children: [
 | 
			
		||||
                    XMLNode(
 | 
			
		||||
                      tag: 'item',
 | 
			
		||||
                      attributes: id != null
 | 
			
		||||
                          ? <String, String>{'id': id}
 | 
			
		||||
                          : <String, String>{},
 | 
			
		||||
                      children: [payload],
 | 
			
		||||
                    )
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
            ],
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
                if (pubOptions != null)
 | 
			
		||||
                  XMLNode(
 | 
			
		||||
                    tag: 'publish-options',
 | 
			
		||||
                    children: [pubOptions.toXml()],
 | 
			
		||||
                  ),
 | 
			
		||||
              ],
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      final error = getPubSubError(result);
 | 
			
		||||
 | 
			
		||||
@ -395,21 +402,26 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
    String jid,
 | 
			
		||||
    String node,
 | 
			
		||||
  ) async {
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        to: jid,
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(tag: 'items', attributes: <String, String>{'node': node}),
 | 
			
		||||
            ],
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          to: jid,
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'items',
 | 
			
		||||
                  attributes: <String, String>{'node': node},
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      return Result(getPubSubError(result));
 | 
			
		||||
@ -436,30 +448,32 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
    String node,
 | 
			
		||||
    String id,
 | 
			
		||||
  ) async {
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        to: jid,
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'items',
 | 
			
		||||
                attributes: <String, String>{'node': node},
 | 
			
		||||
                children: [
 | 
			
		||||
                  XMLNode(
 | 
			
		||||
                    tag: 'item',
 | 
			
		||||
                    attributes: <String, String>{'id': id},
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          to: jid,
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'items',
 | 
			
		||||
                  attributes: <String, String>{'node': node},
 | 
			
		||||
                  children: [
 | 
			
		||||
                    XMLNode(
 | 
			
		||||
                      tag: 'item',
 | 
			
		||||
                      attributes: <String, String>{'id': id},
 | 
			
		||||
                    ),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      return Result(getPubSubError(result));
 | 
			
		||||
@ -488,53 +502,57 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
 | 
			
		||||
    // Request the form
 | 
			
		||||
    final form = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        to: jid.toString(),
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubOwnerXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'configure',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'node': node,
 | 
			
		||||
                },
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
    final form = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          to: jid.toString(),
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubOwnerXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'configure',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'node': node,
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
    if (form.attributes['type'] != 'result') {
 | 
			
		||||
      return Result(getPubSubError(form));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final submit = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        to: jid.toString(),
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubOwnerXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'configure',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'node': node,
 | 
			
		||||
                },
 | 
			
		||||
                children: [
 | 
			
		||||
                  options.toXml(),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
    final submit = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          to: jid.toString(),
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubOwnerXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'configure',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'node': node,
 | 
			
		||||
                  },
 | 
			
		||||
                  children: [
 | 
			
		||||
                    options.toXml(),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
    if (submit.attributes['type'] != 'result') {
 | 
			
		||||
      return Result(getPubSubError(form));
 | 
			
		||||
    }
 | 
			
		||||
@ -543,28 +561,30 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<Result<PubSubError, bool>> delete(JID host, String node) async {
 | 
			
		||||
    final request = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        to: host.toString(),
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubOwnerXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'delete',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'node': node,
 | 
			
		||||
                },
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
    final request = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          to: host.toString(),
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubOwnerXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'delete',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'node': node,
 | 
			
		||||
                  },
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    ) as Stanza;
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (request.type != 'result') {
 | 
			
		||||
    if (request.attributes['type'] != 'result') {
 | 
			
		||||
      // TODO(Unknown): Be more specific
 | 
			
		||||
      return Result(UnknownPubSubError());
 | 
			
		||||
    }
 | 
			
		||||
@ -577,36 +597,38 @@ class PubSubManager extends XmppManagerBase {
 | 
			
		||||
    String node,
 | 
			
		||||
    String itemId,
 | 
			
		||||
  ) async {
 | 
			
		||||
    final request = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        to: host.toString(),
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'pubsub',
 | 
			
		||||
            xmlns: pubsubXmlns,
 | 
			
		||||
            children: [
 | 
			
		||||
              XMLNode(
 | 
			
		||||
                tag: 'retract',
 | 
			
		||||
                attributes: <String, String>{
 | 
			
		||||
                  'node': node,
 | 
			
		||||
                },
 | 
			
		||||
                children: [
 | 
			
		||||
                  XMLNode(
 | 
			
		||||
                    tag: 'item',
 | 
			
		||||
                    attributes: <String, String>{
 | 
			
		||||
                      'id': itemId,
 | 
			
		||||
                    },
 | 
			
		||||
                  ),
 | 
			
		||||
                ],
 | 
			
		||||
              ),
 | 
			
		||||
            ],
 | 
			
		||||
          ),
 | 
			
		||||
        ],
 | 
			
		||||
    final request = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          to: host.toString(),
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'pubsub',
 | 
			
		||||
              xmlns: pubsubXmlns,
 | 
			
		||||
              children: [
 | 
			
		||||
                XMLNode(
 | 
			
		||||
                  tag: 'retract',
 | 
			
		||||
                  attributes: <String, String>{
 | 
			
		||||
                    'node': node,
 | 
			
		||||
                  },
 | 
			
		||||
                  children: [
 | 
			
		||||
                    XMLNode(
 | 
			
		||||
                      tag: 'item',
 | 
			
		||||
                      attributes: <String, String>{
 | 
			
		||||
                        'id': itemId,
 | 
			
		||||
                      },
 | 
			
		||||
                    ),
 | 
			
		||||
                  ],
 | 
			
		||||
                ),
 | 
			
		||||
              ],
 | 
			
		||||
            ),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    ) as Stanza;
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (request.type != 'result') {
 | 
			
		||||
    if (request.attributes['type'] != 'result') {
 | 
			
		||||
      // TODO(Unknown): Be more specific
 | 
			
		||||
      return Result(UnknownPubSubError());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import 'package:moxxmpp/src/managers/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
 | 
			
		||||
enum ChatState { active, composing, paused, inactive, gone }
 | 
			
		||||
 | 
			
		||||
@ -111,10 +112,14 @@ class ChatStateManager extends XmppManagerBase {
 | 
			
		||||
    final tagName = state.toString().split('.').last;
 | 
			
		||||
 | 
			
		||||
    getAttributes().sendStanza(
 | 
			
		||||
      Stanza.message(
 | 
			
		||||
        to: to,
 | 
			
		||||
        type: messageType,
 | 
			
		||||
        children: [XMLNode.xmlns(tag: tagName, xmlns: chatStateXmlns)],
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.message(
 | 
			
		||||
          to: to,
 | 
			
		||||
          type: messageType,
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(tag: tagName, xmlns: chatStateXmlns),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -6,6 +6,7 @@ import 'package:moxxmpp/src/managers/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
 | 
			
		||||
 | 
			
		||||
class BlockingManager extends XmppManagerBase {
 | 
			
		||||
@ -96,39 +97,43 @@ class BlockingManager extends XmppManagerBase {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<bool> block(List<String> items) async {
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'block',
 | 
			
		||||
            xmlns: blockingXmlns,
 | 
			
		||||
            children: items.map((item) {
 | 
			
		||||
              return XMLNode(
 | 
			
		||||
                tag: 'item',
 | 
			
		||||
                attributes: <String, String>{'jid': item},
 | 
			
		||||
              );
 | 
			
		||||
            }).toList(),
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'block',
 | 
			
		||||
              xmlns: blockingXmlns,
 | 
			
		||||
              children: items.map((item) {
 | 
			
		||||
                return XMLNode(
 | 
			
		||||
                  tag: 'item',
 | 
			
		||||
                  attributes: <String, String>{'jid': item},
 | 
			
		||||
                );
 | 
			
		||||
              }).toList(),
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    return result.attributes['type'] == 'result';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<bool> unblockAll() async {
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'unblock',
 | 
			
		||||
            xmlns: blockingXmlns,
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'unblock',
 | 
			
		||||
              xmlns: blockingXmlns,
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    return result.attributes['type'] == 'result';
 | 
			
		||||
  }
 | 
			
		||||
@ -136,41 +141,45 @@ class BlockingManager extends XmppManagerBase {
 | 
			
		||||
  Future<bool> unblock(List<String> items) async {
 | 
			
		||||
    assert(items.isNotEmpty, 'The list of items to unblock must be non-empty');
 | 
			
		||||
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'unblock',
 | 
			
		||||
            xmlns: blockingXmlns,
 | 
			
		||||
            children: items
 | 
			
		||||
                .map(
 | 
			
		||||
                  (item) => XMLNode(
 | 
			
		||||
                    tag: 'item',
 | 
			
		||||
                    attributes: <String, String>{'jid': item},
 | 
			
		||||
                  ),
 | 
			
		||||
                )
 | 
			
		||||
                .toList(),
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'unblock',
 | 
			
		||||
              xmlns: blockingXmlns,
 | 
			
		||||
              children: items
 | 
			
		||||
                  .map(
 | 
			
		||||
                    (item) => XMLNode(
 | 
			
		||||
                      tag: 'item',
 | 
			
		||||
                      attributes: <String, String>{'jid': item},
 | 
			
		||||
                    ),
 | 
			
		||||
                  )
 | 
			
		||||
                  .toList(),
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    return result.attributes['type'] == 'result';
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  Future<List<String>> getBlocklist() async {
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'blocklist',
 | 
			
		||||
            xmlns: blockingXmlns,
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'blocklist',
 | 
			
		||||
              xmlns: blockingXmlns,
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    final blocklist = result.firstTag('blocklist', xmlns: blockingXmlns)!;
 | 
			
		||||
    return blocklist
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@ import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0198/errors.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0198/negotiator.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0198/nonzas.dart';
 | 
			
		||||
@ -414,7 +415,12 @@ class StreamManagementManager extends XmppManagerBase {
 | 
			
		||||
    _unackedStanzas.clear();
 | 
			
		||||
 | 
			
		||||
    for (final stanza in stanzas) {
 | 
			
		||||
      await getAttributes().sendStanza(stanza, awaitable: false);
 | 
			
		||||
      await getAttributes().sendStanza(
 | 
			
		||||
        StanzaDetails(
 | 
			
		||||
          stanza,
 | 
			
		||||
          awaitable: false,
 | 
			
		||||
        ),
 | 
			
		||||
      );
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,6 +1,5 @@
 | 
			
		||||
import 'package:logging/logging.dart';
 | 
			
		||||
import 'package:meta/meta.dart';
 | 
			
		||||
import 'package:moxxmpp/src/connection.dart';
 | 
			
		||||
import 'package:moxxmpp/src/events.dart';
 | 
			
		||||
import 'package:moxxmpp/src/jid.dart';
 | 
			
		||||
import 'package:moxxmpp/src/managers/base.dart';
 | 
			
		||||
@ -11,6 +10,7 @@ import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0297.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0386.dart';
 | 
			
		||||
@ -111,20 +111,20 @@ class CarbonsManager extends XmppManagerBase {
 | 
			
		||||
  /// Returns true if carbons were enabled. False, if not.
 | 
			
		||||
  Future<bool> enableCarbons() async {
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    final result = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        to: attrs.getFullJID().toBare().toString(),
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'enable',
 | 
			
		||||
            xmlns: carbonsXmlns,
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          to: attrs.getFullJID().toBare().toString(),
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'enable',
 | 
			
		||||
              xmlns: carbonsXmlns,
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
      addFrom: StanzaFromType.full,
 | 
			
		||||
      addId: true,
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      logger.warning('Failed to enable message carbons');
 | 
			
		||||
@ -142,19 +142,19 @@ class CarbonsManager extends XmppManagerBase {
 | 
			
		||||
  ///
 | 
			
		||||
  /// Returns true if carbons were disabled. False, if not.
 | 
			
		||||
  Future<bool> disableCarbons() async {
 | 
			
		||||
    final result = await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        type: 'set',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'disable',
 | 
			
		||||
            xmlns: carbonsXmlns,
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final result = (await getAttributes().sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          type: 'set',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'disable',
 | 
			
		||||
              xmlns: carbonsXmlns,
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
      addFrom: StanzaFromType.full,
 | 
			
		||||
      addId: true,
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (result.attributes['type'] != 'result') {
 | 
			
		||||
      logger.warning('Failed to disable message carbons');
 | 
			
		||||
 | 
			
		||||
@ -8,6 +8,7 @@ import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/types/result.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/errors.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/types.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
 | 
			
		||||
@ -149,23 +150,25 @@ class HttpFileUploadManager extends XmppManagerBase {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    final attrs = getAttributes();
 | 
			
		||||
    final response = await attrs.sendStanza(
 | 
			
		||||
      Stanza.iq(
 | 
			
		||||
        to: _entityJid.toString(),
 | 
			
		||||
        type: 'get',
 | 
			
		||||
        children: [
 | 
			
		||||
          XMLNode.xmlns(
 | 
			
		||||
            tag: 'request',
 | 
			
		||||
            xmlns: httpFileUploadXmlns,
 | 
			
		||||
            attributes: {
 | 
			
		||||
              'filename': filename,
 | 
			
		||||
              'size': filesize.toString(),
 | 
			
		||||
              ...contentType != null ? {'content-type': contentType} : {}
 | 
			
		||||
            },
 | 
			
		||||
          )
 | 
			
		||||
        ],
 | 
			
		||||
    final response = (await attrs.sendStanza(
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.iq(
 | 
			
		||||
          to: _entityJid.toString(),
 | 
			
		||||
          type: 'get',
 | 
			
		||||
          children: [
 | 
			
		||||
            XMLNode.xmlns(
 | 
			
		||||
              tag: 'request',
 | 
			
		||||
              xmlns: httpFileUploadXmlns,
 | 
			
		||||
              attributes: {
 | 
			
		||||
                'filename': filename,
 | 
			
		||||
                'size': filesize.toString(),
 | 
			
		||||
                ...contentType != null ? {'content-type': contentType} : {}
 | 
			
		||||
              },
 | 
			
		||||
            )
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
    ))!;
 | 
			
		||||
 | 
			
		||||
    if (response.attributes['type']! != 'result') {
 | 
			
		||||
      logger.severe('Failed to request HTTP File Upload slot.');
 | 
			
		||||
 | 
			
		||||
@ -11,6 +11,7 @@ import 'package:moxxmpp/src/namespaces.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stanza.dart';
 | 
			
		||||
import 'package:moxxmpp/src/stringxml.dart';
 | 
			
		||||
import 'package:moxxmpp/src/types/result.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/errors.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/types.dart';
 | 
			
		||||
import 'package:moxxmpp/src/xeps/xep_0030/xep_0030.dart';
 | 
			
		||||
@ -262,24 +263,26 @@ abstract class BaseOmemoManager extends XmppManagerBase {
 | 
			
		||||
    String toJid,
 | 
			
		||||
  ) async {
 | 
			
		||||
    await getAttributes().sendStanza(
 | 
			
		||||
      Stanza.message(
 | 
			
		||||
        to: toJid,
 | 
			
		||||
        type: 'chat',
 | 
			
		||||
        children: [
 | 
			
		||||
          _buildEncryptedElement(
 | 
			
		||||
            result,
 | 
			
		||||
            toJid,
 | 
			
		||||
            await _getDeviceId(),
 | 
			
		||||
          ),
 | 
			
		||||
      StanzaDetails(
 | 
			
		||||
        Stanza.message(
 | 
			
		||||
          to: toJid,
 | 
			
		||||
          type: 'chat',
 | 
			
		||||
          children: [
 | 
			
		||||
            _buildEncryptedElement(
 | 
			
		||||
              result,
 | 
			
		||||
              toJid,
 | 
			
		||||
              await _getDeviceId(),
 | 
			
		||||
            ),
 | 
			
		||||
 | 
			
		||||
          // Add a storage hint in case this is a message
 | 
			
		||||
          // Taken from the example at
 | 
			
		||||
          // https://xmpp.org/extensions/xep-0384.html#message-structure-description.
 | 
			
		||||
          MessageProcessingHint.store.toXml(),
 | 
			
		||||
        ],
 | 
			
		||||
            // Add a storage hint in case this is a message
 | 
			
		||||
            // Taken from the example at
 | 
			
		||||
            // https://xmpp.org/extensions/xep-0384.html#message-structure-description.
 | 
			
		||||
            MessageProcessingHint.store.toXml(),
 | 
			
		||||
          ],
 | 
			
		||||
        ),
 | 
			
		||||
        awaitable: false,
 | 
			
		||||
        encrypted: true,
 | 
			
		||||
      ),
 | 
			
		||||
      awaitable: false,
 | 
			
		||||
      encrypted: true,
 | 
			
		||||
    );
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,5 +1,6 @@
 | 
			
		||||
import 'dart:async';
 | 
			
		||||
import 'package:moxxmpp/moxxmpp.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:test/test.dart';
 | 
			
		||||
import '../helpers/logging.dart';
 | 
			
		||||
import '../helpers/xmpp.dart';
 | 
			
		||||
@ -44,15 +45,8 @@ Future<void> runOutgoingStanzaHandlers(
 | 
			
		||||
 | 
			
		||||
XmppManagerAttributes mkAttributes(void Function(Stanza) callback) {
 | 
			
		||||
  return XmppManagerAttributes(
 | 
			
		||||
    sendStanza: (
 | 
			
		||||
      stanza, {
 | 
			
		||||
      StanzaFromType addFrom = StanzaFromType.full,
 | 
			
		||||
      bool addId = true,
 | 
			
		||||
      bool awaitable = true,
 | 
			
		||||
      bool encrypted = false,
 | 
			
		||||
      bool forceEncryption = false,
 | 
			
		||||
    }) async {
 | 
			
		||||
      callback(stanza);
 | 
			
		||||
    sendStanza: (StanzaDetails details) async {
 | 
			
		||||
      callback(details.stanza);
 | 
			
		||||
 | 
			
		||||
      return Stanza.message();
 | 
			
		||||
    },
 | 
			
		||||
@ -290,12 +284,8 @@ void main() {
 | 
			
		||||
        );
 | 
			
		||||
      final sm = StreamManagementManager();
 | 
			
		||||
      await conn.registerManagers([
 | 
			
		||||
        PresenceManager(),
 | 
			
		||||
        RosterManager(TestingRosterStateManager('', [])),
 | 
			
		||||
        DiscoManager([]),
 | 
			
		||||
        sm,
 | 
			
		||||
        CarbonsManager()..forceEnable(),
 | 
			
		||||
        EntityCapabilitiesManager('http://moxxmpp.example'),
 | 
			
		||||
      ]);
 | 
			
		||||
      await conn.registerFeatureNegotiators([
 | 
			
		||||
        SaslPlainNegotiator(),
 | 
			
		||||
@ -776,7 +766,11 @@ void main() {
 | 
			
		||||
 | 
			
		||||
    // Send a bogus stanza
 | 
			
		||||
    unawaited(
 | 
			
		||||
      conn.sendStanza(Stanza.iq(to: 'localhost', type: 'get')),
 | 
			
		||||
      conn.sendStanza(
 | 
			
		||||
        StanzaDetails(
 | 
			
		||||
          Stanza.iq(to: 'localhost', type: 'get'),
 | 
			
		||||
        ),
 | 
			
		||||
      ),
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    await Future<void>.delayed(const Duration(seconds: 5));
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,5 @@
 | 
			
		||||
import 'package:moxxmpp/moxxmpp.dart';
 | 
			
		||||
import 'package:moxxmpp/src/util/queue.dart';
 | 
			
		||||
import 'package:test/test.dart';
 | 
			
		||||
import '../helpers/logging.dart';
 | 
			
		||||
import '../helpers/xmpp.dart';
 | 
			
		||||
@ -9,17 +10,9 @@ void main() {
 | 
			
		||||
  test("Test if we're vulnerable against CVE-2020-26547 style vulnerabilities",
 | 
			
		||||
      () async {
 | 
			
		||||
    final attributes = XmppManagerAttributes(
 | 
			
		||||
      sendStanza: (
 | 
			
		||||
        stanza, {
 | 
			
		||||
        StanzaFromType addFrom = StanzaFromType.full,
 | 
			
		||||
        bool addId = true,
 | 
			
		||||
        bool retransmitted = false,
 | 
			
		||||
        bool awaitable = true,
 | 
			
		||||
        bool encrypted = false,
 | 
			
		||||
        bool forceEncryption = false,
 | 
			
		||||
      }) async {
 | 
			
		||||
      sendStanza: (StanzaDetails details) async {
 | 
			
		||||
        // ignore: avoid_print
 | 
			
		||||
        print('==> ${stanza.toXml()}');
 | 
			
		||||
        print('==> ${details.stanza.toXml()}');
 | 
			
		||||
        return XMLNode(tag: 'iq', attributes: {'type': 'result'});
 | 
			
		||||
      },
 | 
			
		||||
      sendNonza: (nonza) {},
 | 
			
		||||
 | 
			
		||||
@ -131,11 +131,7 @@ void main() {
 | 
			
		||||
        password: 'aaaa',
 | 
			
		||||
      );
 | 
			
		||||
    await conn.registerManagers([
 | 
			
		||||
      PresenceManager(),
 | 
			
		||||
      RosterManager(TestingRosterStateManager('', [])),
 | 
			
		||||
      DiscoManager([]),
 | 
			
		||||
      StreamManagementManager(),
 | 
			
		||||
      EntityCapabilitiesManager('http://moxxmpp.example'),
 | 
			
		||||
    ]);
 | 
			
		||||
    await conn.registerFeatureNegotiators([
 | 
			
		||||
      SaslPlainNegotiator(),
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user