Compare commits
No commits in common. "dc24b3c48a5f357d4ccb65f4ad2aed8909aeeffa" and "63c84d94798eb0dec9b5ab27a015c0c91feabcf6" have entirely different histories.
dc24b3c48a
...
63c84d9479
@ -52,9 +52,5 @@ log = {
|
|||||||
|
|
||||||
pidfile = "/tmp/prosody.pid"
|
pidfile = "/tmp/prosody.pid"
|
||||||
|
|
||||||
component_ports = { 8888 }
|
|
||||||
component_interfaces = { '127.0.0.1' }
|
|
||||||
VirtualHost "localhost"
|
VirtualHost "localhost"
|
||||||
|
|
||||||
Component "component.localhost"
|
|
||||||
component_secret = "abc123"
|
|
@ -1,46 +0,0 @@
|
|||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:moxxmpp/moxxmpp.dart';
|
|
||||||
import 'package:moxxmpp_socket_tcp/moxxmpp_socket_tcp.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
|
|
||||||
class TestingTCPSocketWrapper extends TCPSocketWrapper {
|
|
||||||
@override
|
|
||||||
bool onBadCertificate(dynamic certificate, String domain) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
Logger.root.level = Level.ALL;
|
|
||||||
Logger.root.onRecord.listen((record) {
|
|
||||||
// ignore: avoid_print
|
|
||||||
print(
|
|
||||||
'[${record.level.name}] (${record.loggerName}) ${record.time}: ${record.message}',
|
|
||||||
);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('Test connecting to prosody as a component', () async {
|
|
||||||
final conn = XmppConnection(
|
|
||||||
TestingReconnectionPolicy(),
|
|
||||||
AlwaysConnectedConnectivityManager(),
|
|
||||||
ComponentToServerNegotiator(),
|
|
||||||
TestingTCPSocketWrapper(),
|
|
||||||
)..connectionSettings = ConnectionSettings(
|
|
||||||
jid: JID.fromString('component.localhost'),
|
|
||||||
password: 'abc123',
|
|
||||||
host: '127.0.0.1',
|
|
||||||
port: 8888,
|
|
||||||
);
|
|
||||||
await conn.registerManagers([
|
|
||||||
RosterManager(TestingRosterStateManager('', [])),
|
|
||||||
DiscoManager([]),
|
|
||||||
]);
|
|
||||||
|
|
||||||
final result = await conn.connect(
|
|
||||||
waitUntilLogin: true,
|
|
||||||
shouldReconnect: false,
|
|
||||||
enableReconnectOnSuccess: false,
|
|
||||||
);
|
|
||||||
expect(result.isType<bool>(), true);
|
|
||||||
});
|
|
||||||
}
|
|
@ -19,18 +19,20 @@ void main() {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Test authenticating against Prosody with SASL2, Bind2, and FAST',
|
test('Test authenticating against Prosody with SASL2, Bind2, and FAST', () async {
|
||||||
() async {
|
|
||||||
final conn = XmppConnection(
|
final conn = XmppConnection(
|
||||||
TestingReconnectionPolicy(),
|
TestingReconnectionPolicy(),
|
||||||
AlwaysConnectedConnectivityManager(),
|
AlwaysConnectedConnectivityManager(),
|
||||||
ClientToServerNegotiator(),
|
|
||||||
TestingTCPSocketWrapper(),
|
TestingTCPSocketWrapper(),
|
||||||
)..connectionSettings = ConnectionSettings(
|
)..setConnectionSettings(
|
||||||
|
ConnectionSettings(
|
||||||
jid: JID.fromString('testuser@localhost'),
|
jid: JID.fromString('testuser@localhost'),
|
||||||
password: 'abc123',
|
password: 'abc123',
|
||||||
|
useDirectTLS: false,
|
||||||
|
|
||||||
host: '127.0.0.1',
|
host: '127.0.0.1',
|
||||||
port: 5222,
|
port: 5222,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
final csi = CSIManager();
|
final csi = CSIManager();
|
||||||
await csi.setInactive(sendNonza: false);
|
await csi.setInactive(sendNonza: false);
|
||||||
@ -59,16 +61,7 @@ void main() {
|
|||||||
enableReconnectOnSuccess: false,
|
enableReconnectOnSuccess: false,
|
||||||
);
|
);
|
||||||
expect(result.isType<bool>(), true);
|
expect(result.isType<bool>(), true);
|
||||||
expect(
|
expect(conn.getNegotiatorById<Sasl2Negotiator>(sasl2Negotiator)!.state, NegotiatorState.done);
|
||||||
conn.getNegotiatorById<Sasl2Negotiator>(sasl2Negotiator)!.state,
|
expect(conn.getNegotiatorById<FASTSaslNegotiator>(saslFASTNegotiator)!.fastToken != null, true,);
|
||||||
NegotiatorState.done,
|
|
||||||
);
|
|
||||||
expect(
|
|
||||||
conn
|
|
||||||
.getNegotiatorById<FASTSaslNegotiator>(saslFASTNegotiator)!
|
|
||||||
.fastToken !=
|
|
||||||
null,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -7,8 +7,6 @@
|
|||||||
- **BREAKING**: Removed `isFeatureSupported` from the manager attributes. The managers now all have a method `isFeatureSupported` that works the same
|
- **BREAKING**: Removed `isFeatureSupported` from the manager attributes. The managers now all have a method `isFeatureSupported` that works the same
|
||||||
- The `PresenceManager` is now optional
|
- The `PresenceManager` is now optional
|
||||||
- **BREAKING**: Removed `setConnectionSettings` and `getConnectionSettings`. Just directly acces the `connectionSettings` field.
|
- **BREAKING**: Removed `setConnectionSettings` and `getConnectionSettings`. Just directly acces the `connectionSettings` field.
|
||||||
- Implement XEP-0144 for implementing components
|
|
||||||
- **BREAKING**: Remove `useDirectTLS` from `ConnectionSettings`
|
|
||||||
|
|
||||||
## 0.1.6+1
|
## 0.1.6+1
|
||||||
|
|
||||||
|
@ -5,9 +5,6 @@ export 'package:moxxmpp/src/connection_errors.dart';
|
|||||||
export 'package:moxxmpp/src/connectivity.dart';
|
export 'package:moxxmpp/src/connectivity.dart';
|
||||||
export 'package:moxxmpp/src/errors.dart';
|
export 'package:moxxmpp/src/errors.dart';
|
||||||
export 'package:moxxmpp/src/events.dart';
|
export 'package:moxxmpp/src/events.dart';
|
||||||
export 'package:moxxmpp/src/handlers/base.dart';
|
|
||||||
export 'package:moxxmpp/src/handlers/client.dart';
|
|
||||||
export 'package:moxxmpp/src/handlers/component.dart';
|
|
||||||
export 'package:moxxmpp/src/iq.dart';
|
export 'package:moxxmpp/src/iq.dart';
|
||||||
export 'package:moxxmpp/src/jid.dart';
|
export 'package:moxxmpp/src/jid.dart';
|
||||||
export 'package:moxxmpp/src/managers/attributes.dart';
|
export 'package:moxxmpp/src/managers/attributes.dart';
|
||||||
@ -18,6 +15,7 @@ export 'package:moxxmpp/src/managers/namespaces.dart';
|
|||||||
export 'package:moxxmpp/src/managers/priorities.dart';
|
export 'package:moxxmpp/src/managers/priorities.dart';
|
||||||
export 'package:moxxmpp/src/message.dart';
|
export 'package:moxxmpp/src/message.dart';
|
||||||
export 'package:moxxmpp/src/namespaces.dart';
|
export 'package:moxxmpp/src/namespaces.dart';
|
||||||
|
export 'package:moxxmpp/src/negotiators/handler.dart';
|
||||||
export 'package:moxxmpp/src/negotiators/manager.dart';
|
export 'package:moxxmpp/src/negotiators/manager.dart';
|
||||||
export 'package:moxxmpp/src/negotiators/namespaces.dart';
|
export 'package:moxxmpp/src/negotiators/namespaces.dart';
|
||||||
export 'package:moxxmpp/src/negotiators/negotiator.dart';
|
export 'package:moxxmpp/src/negotiators/negotiator.dart';
|
||||||
|
@ -8,13 +8,15 @@ import 'package:moxxmpp/src/connection_errors.dart';
|
|||||||
import 'package:moxxmpp/src/connectivity.dart';
|
import 'package:moxxmpp/src/connectivity.dart';
|
||||||
import 'package:moxxmpp/src/errors.dart';
|
import 'package:moxxmpp/src/errors.dart';
|
||||||
import 'package:moxxmpp/src/events.dart';
|
import 'package:moxxmpp/src/events.dart';
|
||||||
import 'package:moxxmpp/src/handlers/base.dart';
|
|
||||||
import 'package:moxxmpp/src/iq.dart';
|
import 'package:moxxmpp/src/iq.dart';
|
||||||
|
import 'package:moxxmpp/src/jid.dart';
|
||||||
import 'package:moxxmpp/src/managers/attributes.dart';
|
import 'package:moxxmpp/src/managers/attributes.dart';
|
||||||
import 'package:moxxmpp/src/managers/base.dart';
|
import 'package:moxxmpp/src/managers/base.dart';
|
||||||
import 'package:moxxmpp/src/managers/data.dart';
|
import 'package:moxxmpp/src/managers/data.dart';
|
||||||
import 'package:moxxmpp/src/managers/handlers.dart';
|
import 'package:moxxmpp/src/managers/handlers.dart';
|
||||||
import 'package:moxxmpp/src/managers/namespaces.dart';
|
import 'package:moxxmpp/src/managers/namespaces.dart';
|
||||||
|
import 'package:moxxmpp/src/namespaces.dart';
|
||||||
|
import 'package:moxxmpp/src/negotiators/handler.dart';
|
||||||
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
import 'package:moxxmpp/src/negotiators/namespaces.dart';
|
||||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
||||||
import 'package:moxxmpp/src/presence.dart';
|
import 'package:moxxmpp/src/presence.dart';
|
||||||
@ -61,6 +63,23 @@ enum StanzaFromType {
|
|||||||
none,
|
none,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Nonza describing the XMPP stream header.
|
||||||
|
class StreamHeaderNonza extends XMLNode {
|
||||||
|
StreamHeaderNonza(JID jid)
|
||||||
|
: super(
|
||||||
|
tag: 'stream:stream',
|
||||||
|
attributes: <String, String>{
|
||||||
|
'xmlns': stanzaXmlns,
|
||||||
|
'version': '1.0',
|
||||||
|
'xmlns:stream': streamXmlns,
|
||||||
|
'to': jid.domain,
|
||||||
|
'from': jid.toBare().toString(),
|
||||||
|
'xml:lang': 'en',
|
||||||
|
},
|
||||||
|
closeTag: false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// This class is a connection to the server.
|
/// This class is a connection to the server.
|
||||||
class XmppConnection {
|
class XmppConnection {
|
||||||
XmppConnection(
|
XmppConnection(
|
||||||
@ -80,9 +99,8 @@ class XmppConnection {
|
|||||||
_negotiationsHandler.register(
|
_negotiationsHandler.register(
|
||||||
_onNegotiationsDone,
|
_onNegotiationsDone,
|
||||||
handleError,
|
handleError,
|
||||||
|
_sendStreamHeaders,
|
||||||
() => _isAuthenticated,
|
() => _isAuthenticated,
|
||||||
sendRawXML,
|
|
||||||
() => connectionSettings,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
_socketStream = _socket.getDataStream();
|
_socketStream = _socket.getDataStream();
|
||||||
@ -750,7 +768,7 @@ class XmppConnection {
|
|||||||
/// Called whenever we receive data that has been parsed as XML.
|
/// Called whenever we receive data that has been parsed as XML.
|
||||||
Future<void> handleXmlStream(XmlStreamBufferObject event) async {
|
Future<void> handleXmlStream(XmlStreamBufferObject event) async {
|
||||||
if (event is XmlStreamBufferHeader) {
|
if (event is XmlStreamBufferHeader) {
|
||||||
await _negotiationsHandler.negotiate(event);
|
_negotiationsHandler.setStreamHeaderId(event.attributes['id']);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -781,11 +799,11 @@ class XmppConnection {
|
|||||||
// prevent this issue.
|
// prevent this issue.
|
||||||
await _negotiationLock.synchronized(() async {
|
await _negotiationLock.synchronized(() async {
|
||||||
if (_routingState != RoutingState.negotiating) {
|
if (_routingState != RoutingState.negotiating) {
|
||||||
unawaited(handleXmlStream(event));
|
unawaited(handleXmlStream(XmlStreamBufferElement(node)));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
await _negotiationsHandler.negotiate(event);
|
await _negotiationsHandler.negotiate(node);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case RoutingState.handleStanzas:
|
case RoutingState.handleStanzas:
|
||||||
@ -815,6 +833,21 @@ class XmppConnection {
|
|||||||
_eventStreamController.add(event);
|
_eventStreamController.add(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Sends a stream header to the socket.
|
||||||
|
void _sendStreamHeaders() {
|
||||||
|
_socket.write(
|
||||||
|
XMLNode(
|
||||||
|
tag: 'xml',
|
||||||
|
attributes: {'version': '1.0'},
|
||||||
|
closeTag: false,
|
||||||
|
isDeclaration: true,
|
||||||
|
children: [
|
||||||
|
StreamHeaderNonza(connectionSettings.jid),
|
||||||
|
],
|
||||||
|
).toXml(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/// Attempt to gracefully close the session
|
/// Attempt to gracefully close the session
|
||||||
Future<void> disconnect() async {
|
Future<void> disconnect() async {
|
||||||
await _disconnect(state: XmppConnectionState.notConnected);
|
await _disconnect(state: XmppConnectionState.notConnected);
|
||||||
@ -922,7 +955,7 @@ class XmppConnection {
|
|||||||
await _setConnectionState(XmppConnectionState.connecting);
|
await _setConnectionState(XmppConnectionState.connecting);
|
||||||
_updateRoutingState(RoutingState.negotiating);
|
_updateRoutingState(RoutingState.negotiating);
|
||||||
_isAuthenticated = false;
|
_isAuthenticated = false;
|
||||||
_negotiationsHandler.sendStreamHeader();
|
_sendStreamHeaders();
|
||||||
|
|
||||||
if (waitUntilLogin) {
|
if (waitUntilLogin) {
|
||||||
return _connectionCompleter!.future;
|
return _connectionCompleter!.future;
|
||||||
|
@ -46,15 +46,3 @@ class NoAuthenticatorAvailableError extends XmppConnectionError {
|
|||||||
@override
|
@override
|
||||||
bool isRecoverable() => false;
|
bool isRecoverable() => false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returned by the negotiation handler if unexpected data has been received
|
|
||||||
class UnexpectedDataError extends XmppConnectionError {
|
|
||||||
@override
|
|
||||||
bool isRecoverable() => false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returned by the ComponentToServerNegotiator if the handshake is not successful.
|
|
||||||
class InvalidHandshakeCredentialsError extends XmppConnectionError {
|
|
||||||
@override
|
|
||||||
bool isRecoverable() => false;
|
|
||||||
}
|
|
||||||
|
@ -1,121 +0,0 @@
|
|||||||
import 'package:logging/logging.dart';
|
|
||||||
import 'package:meta/meta.dart';
|
|
||||||
import 'package:moxxmpp/src/buffer.dart';
|
|
||||||
import 'package:moxxmpp/src/errors.dart';
|
|
||||||
import 'package:moxxmpp/src/events.dart';
|
|
||||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
|
||||||
import 'package:moxxmpp/src/settings.dart';
|
|
||||||
import 'package:moxxmpp/src/stringxml.dart';
|
|
||||||
|
|
||||||
/// A callback for when the [NegotiationsHandler] is done.
|
|
||||||
typedef NegotiationsDoneCallback = Future<void> Function();
|
|
||||||
|
|
||||||
/// A callback for the case that an error occurs while negotiating.
|
|
||||||
typedef ErrorCallback = Future<void> Function(XmppError);
|
|
||||||
|
|
||||||
/// Return true if the current connection is authenticated. If not, return false.
|
|
||||||
typedef IsAuthenticatedFunction = bool Function();
|
|
||||||
|
|
||||||
/// Send a nonza on the stream
|
|
||||||
typedef SendNonzaFunction = void Function(XMLNode);
|
|
||||||
|
|
||||||
/// Returns the connection settings.
|
|
||||||
typedef GetConnectionSettingsFunction = ConnectionSettings Function();
|
|
||||||
|
|
||||||
/// This class implements the stream feature negotiation for XmppConnection.
|
|
||||||
abstract class NegotiationsHandler {
|
|
||||||
@protected
|
|
||||||
late final Logger log;
|
|
||||||
|
|
||||||
/// Map of all negotiators registered against the handler.
|
|
||||||
@protected
|
|
||||||
final Map<String, XmppFeatureNegotiatorBase> negotiators = {};
|
|
||||||
|
|
||||||
/// Function that is called once the negotiator is done with its stream negotiations.
|
|
||||||
@protected
|
|
||||||
late final NegotiationsDoneCallback onNegotiationsDone;
|
|
||||||
|
|
||||||
/// XmppConnection's handleError method.
|
|
||||||
@protected
|
|
||||||
late final ErrorCallback handleError;
|
|
||||||
|
|
||||||
/// Returns true if the connection is authenticated. If not, returns false.
|
|
||||||
@protected
|
|
||||||
late final IsAuthenticatedFunction isAuthenticated;
|
|
||||||
|
|
||||||
/// Send a nonza over the stream.
|
|
||||||
@protected
|
|
||||||
late final SendNonzaFunction sendNonza;
|
|
||||||
|
|
||||||
/// Get the connection's settings.
|
|
||||||
@protected
|
|
||||||
late final GetConnectionSettingsFunction getConnectionSettings;
|
|
||||||
|
|
||||||
/// The id included in the last stream header.
|
|
||||||
@protected
|
|
||||||
String? streamId;
|
|
||||||
|
|
||||||
/// Set the id of the last stream header.
|
|
||||||
void setStreamHeaderId(String? id) {
|
|
||||||
streamId = id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns, if registered, a negotiator with id [id].
|
|
||||||
T? getNegotiatorById<T extends XmppFeatureNegotiatorBase>(String id) =>
|
|
||||||
negotiators[id] as T?;
|
|
||||||
|
|
||||||
/// Register the parameters as the corresponding methods in this class. Also
|
|
||||||
/// initializes the logger.
|
|
||||||
void register(
|
|
||||||
NegotiationsDoneCallback onNegotiationsDone,
|
|
||||||
ErrorCallback handleError,
|
|
||||||
IsAuthenticatedFunction isAuthenticated,
|
|
||||||
SendNonzaFunction sendNonza,
|
|
||||||
GetConnectionSettingsFunction getConnectionSettings,
|
|
||||||
) {
|
|
||||||
this.onNegotiationsDone = onNegotiationsDone;
|
|
||||||
this.handleError = handleError;
|
|
||||||
this.isAuthenticated = isAuthenticated;
|
|
||||||
this.sendNonza = sendNonza;
|
|
||||||
this.getConnectionSettings = getConnectionSettings;
|
|
||||||
log = Logger(toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Registers the negotiator [negotiator] against this negotiations handler.
|
|
||||||
void registerNegotiator(XmppFeatureNegotiatorBase negotiator);
|
|
||||||
|
|
||||||
/// Sends the stream header.
|
|
||||||
void sendStreamHeader();
|
|
||||||
|
|
||||||
/// Runs the post-register callback of all negotiators.
|
|
||||||
Future<void> runPostRegisterCallback() async {
|
|
||||||
for (final negotiator in negotiators.values) {
|
|
||||||
await negotiator.postRegisterCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> sendEventToNegotiators(XmppEvent event) async {
|
|
||||||
for (final negotiator in negotiators.values) {
|
|
||||||
await negotiator.onXmppEvent(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Remove [feature] from the stream features we are currently negotiating.
|
|
||||||
void removeNegotiatingFeature(String feature) {}
|
|
||||||
|
|
||||||
/// Resets all registered negotiators and the negotiation handler.
|
|
||||||
@mustCallSuper
|
|
||||||
void reset() {
|
|
||||||
streamId = null;
|
|
||||||
for (final negotiator in negotiators.values) {
|
|
||||||
negotiator.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Called whenever the stream buffer outputs a new event [event].
|
|
||||||
Future<void> negotiate(XmlStreamBufferObject event) async {
|
|
||||||
if (event is XmlStreamBufferHeader) {
|
|
||||||
streamId = event.attributes['id'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,117 +0,0 @@
|
|||||||
import 'dart:convert';
|
|
||||||
import 'package:cryptography/cryptography.dart';
|
|
||||||
import 'package:hex/hex.dart';
|
|
||||||
import 'package:moxxmpp/src/buffer.dart';
|
|
||||||
import 'package:moxxmpp/src/connection_errors.dart';
|
|
||||||
import 'package:moxxmpp/src/handlers/base.dart';
|
|
||||||
import 'package:moxxmpp/src/jid.dart';
|
|
||||||
import 'package:moxxmpp/src/namespaces.dart';
|
|
||||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
|
||||||
import 'package:moxxmpp/src/stringxml.dart';
|
|
||||||
|
|
||||||
/// Nonza describing the XMPP stream header.
|
|
||||||
class ComponentStreamHeaderNonza extends XMLNode {
|
|
||||||
ComponentStreamHeaderNonza(JID jid)
|
|
||||||
: assert(jid.isBare(), 'Component JID must be bare'),
|
|
||||||
super(
|
|
||||||
tag: 'stream:stream',
|
|
||||||
attributes: <String, String>{
|
|
||||||
'xmlns': componentAcceptXmlns,
|
|
||||||
'xmlns:stream': streamXmlns,
|
|
||||||
'to': jid.domain,
|
|
||||||
},
|
|
||||||
closeTag: false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The states the ComponentToServerNegotiator can be in.
|
|
||||||
enum ComponentToServerState {
|
|
||||||
/// No data has been sent or received yet
|
|
||||||
idle,
|
|
||||||
|
|
||||||
/// Handshake has been sent
|
|
||||||
handshakeSent,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The ComponentToServerNegotiator is a NegotiationsHandler that allows writing
|
|
||||||
/// components that adhere to XEP-0114.
|
|
||||||
class ComponentToServerNegotiator extends NegotiationsHandler {
|
|
||||||
ComponentToServerNegotiator();
|
|
||||||
|
|
||||||
/// The state the negotiation handler is currently in
|
|
||||||
ComponentToServerState _state = ComponentToServerState.idle;
|
|
||||||
|
|
||||||
@override
|
|
||||||
void registerNegotiator(XmppFeatureNegotiatorBase negotiator) {}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void sendStreamHeader() {
|
|
||||||
sendNonza(
|
|
||||||
XMLNode(
|
|
||||||
tag: 'xml',
|
|
||||||
attributes: {'version': '1.0'},
|
|
||||||
closeTag: false,
|
|
||||||
isDeclaration: true,
|
|
||||||
children: [
|
|
||||||
ComponentStreamHeaderNonza(getConnectionSettings().jid),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<String> _computeHandshake(String id) async {
|
|
||||||
final secret = getConnectionSettings().password;
|
|
||||||
return HEX.encode(
|
|
||||||
(await Sha1().hash(utf8.encode('$streamId$secret'))).bytes,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<void> negotiate(XmlStreamBufferObject event) async {
|
|
||||||
switch (_state) {
|
|
||||||
case ComponentToServerState.idle:
|
|
||||||
if (event is XmlStreamBufferHeader) {
|
|
||||||
streamId = event.attributes['id'];
|
|
||||||
assert(
|
|
||||||
streamId != null,
|
|
||||||
'The server must respond with a stream header that contains an id',
|
|
||||||
);
|
|
||||||
|
|
||||||
_state = ComponentToServerState.handshakeSent;
|
|
||||||
sendNonza(
|
|
||||||
XMLNode(
|
|
||||||
tag: 'handshake',
|
|
||||||
text: await _computeHandshake(streamId!),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
log.severe('Unexpected data received');
|
|
||||||
await handleError(UnexpectedDataError());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case ComponentToServerState.handshakeSent:
|
|
||||||
if (event is XmlStreamBufferElement) {
|
|
||||||
if (event.node.tag == 'handshake' &&
|
|
||||||
event.node.children.isEmpty &&
|
|
||||||
event.node.attributes.isEmpty) {
|
|
||||||
log.info('Successfully authenticated as component');
|
|
||||||
await onNegotiationsDone();
|
|
||||||
} else {
|
|
||||||
log.warning('Handshake failed');
|
|
||||||
await handleError(InvalidHandshakeCredentialsError());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.severe('Unexpected data received');
|
|
||||||
await handleError(UnexpectedDataError());
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
void reset() {
|
|
||||||
_state = ComponentToServerState.idle;
|
|
||||||
|
|
||||||
super.reset();
|
|
||||||
}
|
|
||||||
}
|
|
@ -44,9 +44,6 @@ const userAvatarMetadataXmlns = 'urn:xmpp:avatar:metadata';
|
|||||||
// XEP-0085
|
// XEP-0085
|
||||||
const chatStateXmlns = 'http://jabber.org/protocol/chatstates';
|
const chatStateXmlns = 'http://jabber.org/protocol/chatstates';
|
||||||
|
|
||||||
// XEP-0114
|
|
||||||
const componentAcceptXmlns = 'jabber:component:accept';
|
|
||||||
|
|
||||||
// XEP-0115
|
// XEP-0115
|
||||||
const capsXmlns = 'http://jabber.org/protocol/caps';
|
const capsXmlns = 'http://jabber.org/protocol/caps';
|
||||||
|
|
||||||
|
@ -1,27 +1,106 @@
|
|||||||
|
import 'package:logging/logging.dart';
|
||||||
import 'package:meta/meta.dart';
|
import 'package:meta/meta.dart';
|
||||||
import 'package:moxxmpp/src/buffer.dart';
|
|
||||||
import 'package:moxxmpp/src/connection_errors.dart';
|
import 'package:moxxmpp/src/connection_errors.dart';
|
||||||
import 'package:moxxmpp/src/handlers/base.dart';
|
import 'package:moxxmpp/src/errors.dart';
|
||||||
import 'package:moxxmpp/src/jid.dart';
|
import 'package:moxxmpp/src/events.dart';
|
||||||
import 'package:moxxmpp/src/namespaces.dart';
|
|
||||||
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
import 'package:moxxmpp/src/negotiators/negotiator.dart';
|
||||||
import 'package:moxxmpp/src/stringxml.dart';
|
import 'package:moxxmpp/src/stringxml.dart';
|
||||||
|
|
||||||
/// "Nonza" describing the XMPP stream header of a client-to-server connection.
|
/// A callback for when the [NegotiationsHandler] is done.
|
||||||
class ClientStreamHeaderNonza extends XMLNode {
|
typedef NegotiationsDoneCallback = Future<void> Function();
|
||||||
ClientStreamHeaderNonza(JID jid)
|
|
||||||
: super(
|
/// A callback for the case that an error occurs while negotiating.
|
||||||
tag: 'stream:stream',
|
typedef ErrorCallback = Future<void> Function(XmppError);
|
||||||
attributes: <String, String>{
|
|
||||||
'xmlns': stanzaXmlns,
|
/// Trigger stream headers to be sent
|
||||||
'version': '1.0',
|
typedef SendStreamHeadersFunction = void Function();
|
||||||
'xmlns:stream': streamXmlns,
|
|
||||||
'to': jid.domain,
|
/// Return true if the current connection is authenticated. If not, return false.
|
||||||
'from': jid.toBare().toString(),
|
typedef IsAuthenticatedFunction = bool Function();
|
||||||
'xml:lang': 'en',
|
|
||||||
},
|
/// This class implements the stream feature negotiation for XmppConnection.
|
||||||
closeTag: false,
|
abstract class NegotiationsHandler {
|
||||||
);
|
@protected
|
||||||
|
late final Logger log;
|
||||||
|
|
||||||
|
/// Map of all negotiators registered against the handler.
|
||||||
|
@protected
|
||||||
|
final Map<String, XmppFeatureNegotiatorBase> negotiators = {};
|
||||||
|
|
||||||
|
/// Function that is called once the negotiator is done with its stream negotiations.
|
||||||
|
@protected
|
||||||
|
late final NegotiationsDoneCallback onNegotiationsDone;
|
||||||
|
|
||||||
|
/// XmppConnection's handleError method.
|
||||||
|
@protected
|
||||||
|
late final ErrorCallback handleError;
|
||||||
|
|
||||||
|
/// Sends stream headers in the stream.
|
||||||
|
@protected
|
||||||
|
late final SendStreamHeadersFunction sendStreamHeaders;
|
||||||
|
|
||||||
|
/// Returns true if the connection is authenticated. If not, returns false.
|
||||||
|
@protected
|
||||||
|
late final IsAuthenticatedFunction isAuthenticated;
|
||||||
|
|
||||||
|
/// The id included in the last stream header.
|
||||||
|
@protected
|
||||||
|
String? streamId;
|
||||||
|
|
||||||
|
/// Set the id of the last stream header.
|
||||||
|
void setStreamHeaderId(String? id) {
|
||||||
|
streamId = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns, if registered, a negotiator with id [id].
|
||||||
|
T? getNegotiatorById<T extends XmppFeatureNegotiatorBase>(String id) =>
|
||||||
|
negotiators[id] as T?;
|
||||||
|
|
||||||
|
/// Register the parameters as the corresponding methods in this class. Also
|
||||||
|
/// initializes the logger.
|
||||||
|
void register(
|
||||||
|
NegotiationsDoneCallback onNegotiationsDone,
|
||||||
|
ErrorCallback handleError,
|
||||||
|
SendStreamHeadersFunction sendStreamHeaders,
|
||||||
|
IsAuthenticatedFunction isAuthenticated,
|
||||||
|
) {
|
||||||
|
this.onNegotiationsDone = onNegotiationsDone;
|
||||||
|
this.handleError = handleError;
|
||||||
|
this.sendStreamHeaders = sendStreamHeaders;
|
||||||
|
this.isAuthenticated = isAuthenticated;
|
||||||
|
log = Logger(toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Registers the negotiator [negotiator] against this negotiations handler.
|
||||||
|
void registerNegotiator(XmppFeatureNegotiatorBase negotiator);
|
||||||
|
|
||||||
|
/// Runs the post-register callback of all negotiators.
|
||||||
|
Future<void> runPostRegisterCallback() async {
|
||||||
|
for (final negotiator in negotiators.values) {
|
||||||
|
await negotiator.postRegisterCallback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> sendEventToNegotiators(XmppEvent event) async {
|
||||||
|
for (final negotiator in negotiators.values) {
|
||||||
|
await negotiator.onXmppEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Remove [feature] from the stream features we are currently negotiating.
|
||||||
|
void removeNegotiatingFeature(String feature) {}
|
||||||
|
|
||||||
|
/// Resets all registered negotiators and the negotiation handler.
|
||||||
|
@mustCallSuper
|
||||||
|
void reset() {
|
||||||
|
streamId = null;
|
||||||
|
for (final negotiator in negotiators.values) {
|
||||||
|
negotiator.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Called whenever a new nonza [nonza] is received while negotiating.
|
||||||
|
Future<void> negotiate(XMLNode nonza);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This class implements the stream feature negotiation for usage in client to server
|
/// This class implements the stream feature negotiation for usage in client to server
|
||||||
@ -55,21 +134,6 @@ class ClientToServerNegotiator extends NegotiationsHandler {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
void sendStreamHeader() {
|
|
||||||
sendNonza(
|
|
||||||
XMLNode(
|
|
||||||
tag: 'xml',
|
|
||||||
attributes: {'version': '1.0'},
|
|
||||||
closeTag: false,
|
|
||||||
isDeclaration: true,
|
|
||||||
children: [
|
|
||||||
ClientStreamHeaderNonza(getConnectionSettings().jid),
|
|
||||||
],
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns true if all mandatory features in [features] have been negotiated.
|
/// Returns true if all mandatory features in [features] have been negotiated.
|
||||||
/// Otherwise returns false.
|
/// Otherwise returns false.
|
||||||
bool _isMandatoryNegotiationDone(List<XMLNode> features) {
|
bool _isMandatoryNegotiationDone(List<XMLNode> features) {
|
||||||
@ -155,7 +219,7 @@ class ClientToServerNegotiator extends NegotiationsHandler {
|
|||||||
if (_currentNegotiator!.sendStreamHeaderWhenDone) {
|
if (_currentNegotiator!.sendStreamHeaderWhenDone) {
|
||||||
_currentNegotiator = null;
|
_currentNegotiator = null;
|
||||||
_streamFeatures.clear();
|
_streamFeatures.clear();
|
||||||
sendStreamHeader();
|
sendStreamHeaders();
|
||||||
} else {
|
} else {
|
||||||
removeNegotiatingFeature(_currentNegotiator!.negotiatingXmlns);
|
removeNegotiatingFeature(_currentNegotiator!.negotiatingXmlns);
|
||||||
_currentNegotiator = null;
|
_currentNegotiator = null;
|
||||||
@ -208,16 +272,14 @@ class ClientToServerNegotiator extends NegotiationsHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> negotiate(XmlStreamBufferObject event) async {
|
Future<void> negotiate(XMLNode nonza) async {
|
||||||
if (event is XmlStreamBufferElement) {
|
if (nonza.tag == 'stream:features') {
|
||||||
if (event.node.tag == 'stream:features') {
|
|
||||||
// Store the received stream features
|
// Store the received stream features
|
||||||
_streamFeatures
|
_streamFeatures
|
||||||
..clear()
|
..clear()
|
||||||
..addAll(event.node.children);
|
..addAll(nonza.children);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _executeCurrentNegotiator(event.node);
|
await _executeCurrentNegotiator(nonza);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,19 +4,14 @@ class ConnectionSettings {
|
|||||||
ConnectionSettings({
|
ConnectionSettings({
|
||||||
required this.jid,
|
required this.jid,
|
||||||
required this.password,
|
required this.password,
|
||||||
|
required this.useDirectTLS,
|
||||||
this.host,
|
this.host,
|
||||||
this.port,
|
this.port,
|
||||||
});
|
});
|
||||||
|
|
||||||
/// The JID to authenticate as.
|
|
||||||
final JID jid;
|
final JID jid;
|
||||||
|
|
||||||
/// The password to use during authentication.
|
|
||||||
final String password;
|
final String password;
|
||||||
|
final bool useDirectTLS;
|
||||||
|
|
||||||
/// The host to connect to. Skips DNS resolution if specified.
|
|
||||||
final String? host;
|
final String? host;
|
||||||
|
|
||||||
/// The port to connect to. Skips DNS resolution if specified.
|
|
||||||
final int? port;
|
final int? port;
|
||||||
}
|
}
|
||||||
|
@ -1,47 +0,0 @@
|
|||||||
import 'package:moxxmpp/moxxmpp.dart';
|
|
||||||
import 'package:test/test.dart';
|
|
||||||
import 'helpers/logging.dart';
|
|
||||||
import 'helpers/xmpp.dart';
|
|
||||||
|
|
||||||
const exampleXmlns1 = 'im:moxxmpp:example1';
|
|
||||||
const exampleNamespace1 = 'im.moxxmpp.test.example1';
|
|
||||||
const exampleXmlns2 = 'im:moxxmpp:example2';
|
|
||||||
const exampleNamespace2 = 'im.moxxmpp.test.example2';
|
|
||||||
|
|
||||||
void main() {
|
|
||||||
initLogger();
|
|
||||||
|
|
||||||
test('Test connecting as a component', () async {
|
|
||||||
final socket = StubTCPSocket([
|
|
||||||
StringExpectation(
|
|
||||||
"<stream:stream xmlns='jabber:component:accept' xmlns:stream='http://etherx.jabber.org/streams' to='component.example.org'>",
|
|
||||||
'''
|
|
||||||
<stream:stream
|
|
||||||
xmlns:stream='http://etherx.jabber.org/streams'
|
|
||||||
xmlns='jabber:component:accept'
|
|
||||||
from='component.example.org'
|
|
||||||
id='3BF96D32'>'''),
|
|
||||||
StringExpectation(
|
|
||||||
'<handshake>ee8567f3b4c6e315345416b45ca2e47dbe921565</handshake>',
|
|
||||||
'<handshake />',
|
|
||||||
),
|
|
||||||
]);
|
|
||||||
final conn = XmppConnection(
|
|
||||||
TestingReconnectionPolicy(),
|
|
||||||
AlwaysConnectedConnectivityManager(),
|
|
||||||
ComponentToServerNegotiator(),
|
|
||||||
socket,
|
|
||||||
)..connectionSettings = ConnectionSettings(
|
|
||||||
jid: JID.fromString('component.example.org'),
|
|
||||||
password: 'abc123',
|
|
||||||
);
|
|
||||||
await conn.registerManagers([
|
|
||||||
RosterManager(TestingRosterStateManager('', [])),
|
|
||||||
DiscoManager([]),
|
|
||||||
]);
|
|
||||||
final result = await conn.connect(
|
|
||||||
waitUntilLogin: true,
|
|
||||||
);
|
|
||||||
expect(result.isType<bool>(), true);
|
|
||||||
});
|
|
||||||
}
|
|
@ -1,10 +1,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'package:moxxmpp/src/connection.dart';
|
import 'package:moxxmpp/src/connection.dart';
|
||||||
import 'package:moxxmpp/src/connectivity.dart';
|
import 'package:moxxmpp/src/connectivity.dart';
|
||||||
import 'package:moxxmpp/src/handlers/client.dart';
|
|
||||||
import 'package:moxxmpp/src/jid.dart';
|
import 'package:moxxmpp/src/jid.dart';
|
||||||
import 'package:moxxmpp/src/managers/attributes.dart';
|
import 'package:moxxmpp/src/managers/attributes.dart';
|
||||||
import 'package:moxxmpp/src/managers/base.dart';
|
import 'package:moxxmpp/src/managers/base.dart';
|
||||||
|
import 'package:moxxmpp/src/negotiators/handler.dart';
|
||||||
import 'package:moxxmpp/src/reconnect.dart';
|
import 'package:moxxmpp/src/reconnect.dart';
|
||||||
import 'package:moxxmpp/src/settings.dart';
|
import 'package:moxxmpp/src/settings.dart';
|
||||||
import 'package:moxxmpp/src/socket.dart';
|
import 'package:moxxmpp/src/socket.dart';
|
||||||
@ -26,6 +26,7 @@ class TestingManagerHolder {
|
|||||||
static final ConnectionSettings settings = ConnectionSettings(
|
static final ConnectionSettings settings = ConnectionSettings(
|
||||||
jid: jid,
|
jid: jid,
|
||||||
password: 'abc123',
|
password: 'abc123',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
|
|
||||||
Future<XMLNode> _sendStanza(
|
Future<XMLNode> _sendStanza(
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import 'package:moxxmpp/moxxmpp.dart';
|
import 'package:moxxmpp/moxxmpp.dart';
|
||||||
import 'package:moxxmpp/src/buffer.dart';
|
|
||||||
import 'package:test/test.dart';
|
import 'package:test/test.dart';
|
||||||
import 'helpers/logging.dart';
|
import 'helpers/logging.dart';
|
||||||
|
//import 'helpers/xmpp.dart';
|
||||||
|
|
||||||
const exampleXmlns1 = 'im:moxxmpp:example1';
|
const exampleXmlns1 = 'im:moxxmpp:example1';
|
||||||
const exampleNamespace1 = 'im.moxxmpp.test.example1';
|
const exampleNamespace1 = 'im.moxxmpp.test.example1';
|
||||||
@ -53,12 +53,8 @@ void main() {
|
|||||||
..register(
|
..register(
|
||||||
() async {},
|
() async {},
|
||||||
(_) async {},
|
(_) async {},
|
||||||
|
() {},
|
||||||
() => false,
|
() => false,
|
||||||
(_) {},
|
|
||||||
() => ConnectionSettings(
|
|
||||||
jid: JID.fromString('test'),
|
|
||||||
password: 'abc123',
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
..registerNegotiator(StubNegotiator1())
|
..registerNegotiator(StubNegotiator1())
|
||||||
..registerNegotiator(StubNegotiator2());
|
..registerNegotiator(StubNegotiator2());
|
||||||
@ -71,19 +67,14 @@ void main() {
|
|||||||
..register(
|
..register(
|
||||||
() async {},
|
() async {},
|
||||||
(_) async {},
|
(_) async {},
|
||||||
|
() {},
|
||||||
() => false,
|
() => false,
|
||||||
(_) {},
|
|
||||||
() => ConnectionSettings(
|
|
||||||
jid: JID.fromString('test'),
|
|
||||||
password: 'abc123',
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
..registerNegotiator(StubNegotiator1())
|
..registerNegotiator(StubNegotiator1())
|
||||||
..registerNegotiator(StubNegotiator2());
|
..registerNegotiator(StubNegotiator2());
|
||||||
await negotiator.runPostRegisterCallback();
|
await negotiator.runPostRegisterCallback();
|
||||||
|
|
||||||
await negotiator.negotiate(
|
await negotiator.negotiate(
|
||||||
XmlStreamBufferElement(
|
|
||||||
XMLNode.fromString(
|
XMLNode.fromString(
|
||||||
'''
|
'''
|
||||||
<stream:features xmlns="http://etherx.jabber.org/streams">
|
<stream:features xmlns="http://etherx.jabber.org/streams">
|
||||||
@ -91,7 +82,6 @@ void main() {
|
|||||||
<example2 xmlns="im:moxxmpp:example2" />
|
<example2 xmlns="im:moxxmpp:example2" />
|
||||||
</stream:features>''',
|
</stream:features>''',
|
||||||
),
|
),
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
|
@ -55,6 +55,7 @@ void main() {
|
|||||||
() => ConnectionSettings(
|
() => ConnectionSettings(
|
||||||
jid: JID.fromString('user@server'),
|
jid: JID.fromString('user@server'),
|
||||||
password: 'pencil',
|
password: 'pencil',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
(_) async {},
|
(_) async {},
|
||||||
getNegotiatorNullStub,
|
getNegotiatorNullStub,
|
||||||
@ -156,6 +157,7 @@ void main() {
|
|||||||
() => ConnectionSettings(
|
() => ConnectionSettings(
|
||||||
jid: JID.fromString('user@server'),
|
jid: JID.fromString('user@server'),
|
||||||
password: 'pencil',
|
password: 'pencil',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
(_) async {},
|
(_) async {},
|
||||||
getNegotiatorNullStub,
|
getNegotiatorNullStub,
|
||||||
@ -212,6 +214,7 @@ void main() {
|
|||||||
() => ConnectionSettings(
|
() => ConnectionSettings(
|
||||||
jid: JID.fromString('user@server'),
|
jid: JID.fromString('user@server'),
|
||||||
password: 'pencil',
|
password: 'pencil',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
(_) async {},
|
(_) async {},
|
||||||
getNegotiatorNullStub,
|
getNegotiatorNullStub,
|
||||||
@ -258,6 +261,7 @@ void main() {
|
|||||||
() => ConnectionSettings(
|
() => ConnectionSettings(
|
||||||
jid: JID.fromString('user@server'),
|
jid: JID.fromString('user@server'),
|
||||||
password: 'pencil',
|
password: 'pencil',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
(_) async {},
|
(_) async {},
|
||||||
getNegotiatorNullStub,
|
getNegotiatorNullStub,
|
||||||
@ -307,6 +311,7 @@ void main() {
|
|||||||
() => ConnectionSettings(
|
() => ConnectionSettings(
|
||||||
jid: JID.fromString('user@server'),
|
jid: JID.fromString('user@server'),
|
||||||
password: 'pencil',
|
password: 'pencil',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
(_) async {},
|
(_) async {},
|
||||||
getNegotiatorNullStub,
|
getNegotiatorNullStub,
|
||||||
|
@ -23,7 +23,7 @@ void main() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
expect(
|
expect(
|
||||||
ClientStreamHeaderNonza(JID.fromString('user@uwu.server')).toXml(),
|
StreamHeaderNonza(JID.fromString('user@uwu.server')).toXml(),
|
||||||
"<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams' to='uwu.server' from='user@uwu.server' xml:lang='en'>",
|
"<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams' to='uwu.server' from='user@uwu.server' xml:lang='en'>",
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -75,6 +75,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
|
@ -61,6 +61,7 @@ XmppManagerAttributes mkAttributes(void Function(Stanza) callback) {
|
|||||||
getConnectionSettings: () => ConnectionSettings(
|
getConnectionSettings: () => ConnectionSettings(
|
||||||
jid: JID.fromString('hallo@example.server'),
|
jid: JID.fromString('hallo@example.server'),
|
||||||
password: 'password',
|
password: 'password',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
getFullJID: () => JID.fromString('hallo@example.server/uwu'),
|
getFullJID: () => JID.fromString('hallo@example.server/uwu'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
@ -285,6 +286,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
final sm = StreamManagementManager();
|
final sm = StreamManagementManager();
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
@ -408,6 +410,166 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
|
);
|
||||||
|
final sm = StreamManagementManager();
|
||||||
|
await conn.registerManagers([
|
||||||
|
PresenceManager(),
|
||||||
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
|
DiscoManager([]),
|
||||||
|
sm,
|
||||||
|
CarbonsManager()..forceEnable(),
|
||||||
|
//EntityCapabilitiesManager('http://moxxmpp.example'),
|
||||||
|
]);
|
||||||
|
await conn.registerFeatureNegotiators([
|
||||||
|
SaslPlainNegotiator(),
|
||||||
|
ResourceBindingNegotiator(),
|
||||||
|
StreamManagementNegotiator(),
|
||||||
|
]);
|
||||||
|
|
||||||
|
await conn.connect(
|
||||||
|
waitUntilLogin: true,
|
||||||
|
);
|
||||||
|
expect(fakeSocket.getState(), 6);
|
||||||
|
expect(await conn.getConnectionState(), XmppConnectionState.connected);
|
||||||
|
expect(
|
||||||
|
conn
|
||||||
|
.getManagerById<StreamManagementManager>(smManager)!
|
||||||
|
.isStreamManagementEnabled(),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
|
||||||
|
// Await an iq
|
||||||
|
await conn.sendStanza(
|
||||||
|
Stanza.iq(
|
||||||
|
to: 'user@example.com',
|
||||||
|
type: 'get',
|
||||||
|
),
|
||||||
|
addFrom: StanzaFromType.none,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(sm.state.s2c, 2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Stream resumption', () {
|
||||||
|
test('Stanza retransmission', () async {
|
||||||
|
var stanzaCount = 0;
|
||||||
|
final attributes = mkAttributes((_) {
|
||||||
|
stanzaCount++;
|
||||||
|
});
|
||||||
|
final manager = StreamManagementManager()..register(attributes);
|
||||||
|
|
||||||
|
await manager.onXmppEvent(
|
||||||
|
StreamManagementEnabledEvent(resource: 'hallo'),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Send 5 stanzas
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
await runOutgoingStanzaHandlers(manager, stanza);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only ack 3
|
||||||
|
// <a h='3' />
|
||||||
|
await manager.runNonzaHandlers(mkAck(3));
|
||||||
|
expect(manager.getUnackedStanzas().length, 2);
|
||||||
|
|
||||||
|
// Lose connection
|
||||||
|
// [ Reconnect ]
|
||||||
|
await manager.onXmppEvent(StreamResumedEvent(h: 3));
|
||||||
|
|
||||||
|
expect(stanzaCount, 2);
|
||||||
|
});
|
||||||
|
test('Resumption with prior state', () async {
|
||||||
|
var stanzaCount = 0;
|
||||||
|
final attributes = mkAttributes((_) {
|
||||||
|
stanzaCount++;
|
||||||
|
});
|
||||||
|
final manager = StreamManagementManager()..register(attributes);
|
||||||
|
|
||||||
|
// [ ... ]
|
||||||
|
await manager.onXmppEvent(
|
||||||
|
StreamManagementEnabledEvent(resource: 'hallo'),
|
||||||
|
);
|
||||||
|
await manager.setState(manager.state.copyWith(c2s: 150, s2c: 70));
|
||||||
|
|
||||||
|
// Send some stanzas but don't ack them
|
||||||
|
for (var i = 0; i < 5; i++) {
|
||||||
|
await runOutgoingStanzaHandlers(manager, stanza);
|
||||||
|
}
|
||||||
|
expect(manager.getUnackedStanzas().length, 5);
|
||||||
|
|
||||||
|
// Lose connection
|
||||||
|
// [ Reconnect ]
|
||||||
|
await manager.onXmppEvent(StreamResumedEvent(h: 150));
|
||||||
|
expect(manager.getUnackedStanzas().length, 0);
|
||||||
|
expect(stanzaCount, 5);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
group('Test the negotiator', () {
|
||||||
|
test('Test successful stream enablement', () async {
|
||||||
|
final fakeSocket = StubTCPSocket([
|
||||||
|
StringExpectation(
|
||||||
|
"<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams' to='test.server' from='polynomdivision@test.server' xml:lang='en'>",
|
||||||
|
'''
|
||||||
|
<stream:stream
|
||||||
|
xmlns="jabber:client"
|
||||||
|
version="1.0"
|
||||||
|
xmlns:stream="http://etherx.jabber.org/streams"
|
||||||
|
from="test.server"
|
||||||
|
xml:lang="en">
|
||||||
|
<stream:features xmlns="http://etherx.jabber.org/streams">
|
||||||
|
<mechanisms xmlns="urn:ietf:params:xml:ns:xmpp-sasl">
|
||||||
|
<mechanism>PLAIN</mechanism>
|
||||||
|
</mechanisms>
|
||||||
|
</stream:features>''',
|
||||||
|
),
|
||||||
|
StringExpectation(
|
||||||
|
"<auth xmlns='urn:ietf:params:xml:ns:xmpp-sasl' mechanism='PLAIN'>AHBvbHlub21kaXZpc2lvbgBhYWFh</auth>",
|
||||||
|
'<success xmlns="urn:ietf:params:xml:ns:xmpp-sasl" />',
|
||||||
|
),
|
||||||
|
StringExpectation(
|
||||||
|
"<stream:stream xmlns='jabber:client' version='1.0' xmlns:stream='http://etherx.jabber.org/streams' to='test.server' from='polynomdivision@test.server' xml:lang='en'>",
|
||||||
|
'''
|
||||||
|
<stream:stream
|
||||||
|
xmlns="jabber:client"
|
||||||
|
version="1.0"
|
||||||
|
xmlns:stream="http://etherx.jabber.org/streams"
|
||||||
|
from="test.server"
|
||||||
|
xml:lang="en">
|
||||||
|
<stream:features xmlns="http://etherx.jabber.org/streams">
|
||||||
|
<bind xmlns="urn:ietf:params:xml:ns:xmpp-bind">
|
||||||
|
<required/>
|
||||||
|
</bind>
|
||||||
|
<session xmlns="urn:ietf:params:xml:ns:xmpp-session">
|
||||||
|
<optional/>
|
||||||
|
</session>
|
||||||
|
<csi xmlns="urn:xmpp:csi:0"/>
|
||||||
|
<sm xmlns="urn:xmpp:sm:3"/>
|
||||||
|
</stream:features>
|
||||||
|
''',
|
||||||
|
),
|
||||||
|
StanzaExpectation(
|
||||||
|
'<iq xmlns="jabber:client" type="set" id="a"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"/></iq>',
|
||||||
|
'<iq xmlns="jabber:client" type="result" id="a"><bind xmlns="urn:ietf:params:xml:ns:xmpp-bind"><jid>polynomdivision@test.server/MU29eEZn</jid></bind></iq>',
|
||||||
|
ignoreId: true,
|
||||||
|
),
|
||||||
|
StringExpectation(
|
||||||
|
"<enable xmlns='urn:xmpp:sm:3' resume='true' />",
|
||||||
|
'<enabled xmlns="urn:xmpp:sm:3" id="some-long-sm-id" resume="true" />',
|
||||||
|
)
|
||||||
|
]);
|
||||||
|
|
||||||
|
final conn = XmppConnection(
|
||||||
|
TestingReconnectionPolicy(),
|
||||||
|
AlwaysConnectedConnectivityManager(),
|
||||||
|
ClientToServerNegotiator(),
|
||||||
|
fakeSocket,
|
||||||
|
)..connectionSettings = ConnectionSettings(
|
||||||
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -500,6 +662,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -589,6 +752,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -675,6 +839,7 @@ void main() {
|
|||||||
..connectionSettings = ConnectionSettings(
|
..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
)
|
)
|
||||||
..setResource('test-resource', triggerEvent: false);
|
..setResource('test-resource', triggerEvent: false);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
@ -772,6 +937,7 @@ void main() {
|
|||||||
..connectionSettings = ConnectionSettings(
|
..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
)
|
)
|
||||||
..setResource('test-resource', triggerEvent: false);
|
..setResource('test-resource', triggerEvent: false);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
@ -873,6 +1039,7 @@ void main() {
|
|||||||
..connectionSettings = ConnectionSettings(
|
..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
)
|
)
|
||||||
..setResource('test-resource', triggerEvent: false);
|
..setResource('test-resource', triggerEvent: false);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
|
@ -28,6 +28,7 @@ void main() {
|
|||||||
getConnectionSettings: () => ConnectionSettings(
|
getConnectionSettings: () => ConnectionSettings(
|
||||||
jid: JID.fromString('bob@xmpp.example'),
|
jid: JID.fromString('bob@xmpp.example'),
|
||||||
password: 'password',
|
password: 'password',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
getFullJID: () => JID.fromString('bob@xmpp.example/uwu'),
|
getFullJID: () => JID.fromString('bob@xmpp.example/uwu'),
|
||||||
getSocket: () => StubTCPSocket([]),
|
getSocket: () => StubTCPSocket([]),
|
||||||
@ -109,6 +110,7 @@ void main() {
|
|||||||
..connectionSettings = ConnectionSettings(
|
..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
)
|
)
|
||||||
..setResource('test-resource', triggerEvent: false);
|
..setResource('test-resource', triggerEvent: false);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
|
@ -54,6 +54,7 @@ void main() {
|
|||||||
getConnectionSettings: () => ConnectionSettings(
|
getConnectionSettings: () => ConnectionSettings(
|
||||||
jid: JID.fromString('some.user@example.server'),
|
jid: JID.fromString('some.user@example.server'),
|
||||||
password: 'password',
|
password: 'password',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getUnsupportedCSINegotiator,
|
getNegotiatorById: getUnsupportedCSINegotiator,
|
||||||
@ -97,6 +98,7 @@ void main() {
|
|||||||
getConnectionSettings: () => ConnectionSettings(
|
getConnectionSettings: () => ConnectionSettings(
|
||||||
jid: JID.fromString('some.user@example.server'),
|
jid: JID.fromString('some.user@example.server'),
|
||||||
password: 'password',
|
password: 'password',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getSupportedCSINegotiator,
|
getNegotiatorById: getSupportedCSINegotiator,
|
||||||
@ -172,6 +174,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
final csi = CSIManager();
|
final csi = CSIManager();
|
||||||
await csi.setInactive(sendNonza: false);
|
await csi.setInactive(sendNonza: false);
|
||||||
|
@ -49,6 +49,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -120,6 +121,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
RosterManager(TestingRosterStateManager('', [])),
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
|
@ -106,6 +106,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -184,6 +185,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('user@server'),
|
jid: JID.fromString('user@server'),
|
||||||
password: 'pencil',
|
password: 'pencil',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -261,6 +263,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('user@server'),
|
jid: JID.fromString('user@server'),
|
||||||
password: 'pencil',
|
password: 'pencil',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -346,6 +349,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -429,6 +433,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
|
@ -112,6 +112,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
RosterManager(TestingRosterStateManager('', [])),
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
@ -225,6 +226,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
RosterManager(TestingRosterStateManager('', [])),
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
|
@ -31,6 +31,7 @@ Future<bool> testRosterManager(
|
|||||||
getConnectionSettings: () => ConnectionSettings(
|
getConnectionSettings: () => ConnectionSettings(
|
||||||
jid: JID.fromString(bareJid),
|
jid: JID.fromString(bareJid),
|
||||||
password: 'password',
|
password: 'password',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getNegotiatorNullStub,
|
getNegotiatorById: getNegotiatorNullStub,
|
||||||
@ -129,6 +130,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -184,6 +186,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -241,6 +244,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('polynomdivision@test.server'),
|
jid: JID.fromString('polynomdivision@test.server'),
|
||||||
password: 'aaaa',
|
password: 'aaaa',
|
||||||
|
useDirectTLS: true,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -286,6 +290,7 @@ void main() {
|
|||||||
getConnectionSettings: () => ConnectionSettings(
|
getConnectionSettings: () => ConnectionSettings(
|
||||||
jid: JID.fromString('some.user@example.server'),
|
jid: JID.fromString('some.user@example.server'),
|
||||||
password: 'password',
|
password: 'password',
|
||||||
|
useDirectTLS: true,
|
||||||
),
|
),
|
||||||
getManagerById: getManagerNullStub,
|
getManagerById: getManagerNullStub,
|
||||||
getNegotiatorById: getNegotiatorNullStub,
|
getNegotiatorById: getNegotiatorNullStub,
|
||||||
@ -398,6 +403,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('testuser@example.org'),
|
jid: JID.fromString('testuser@example.org'),
|
||||||
password: 'abc123',
|
password: 'abc123',
|
||||||
|
useDirectTLS: false,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
PresenceManager(),
|
PresenceManager(),
|
||||||
@ -491,6 +497,7 @@ void main() {
|
|||||||
)..connectionSettings = ConnectionSettings(
|
)..connectionSettings = ConnectionSettings(
|
||||||
jid: JID.fromString('testuser@example.org'),
|
jid: JID.fromString('testuser@example.org'),
|
||||||
password: 'abc123',
|
password: 'abc123',
|
||||||
|
useDirectTLS: false,
|
||||||
);
|
);
|
||||||
await conn.registerManagers([
|
await conn.registerManagers([
|
||||||
RosterManager(TestingRosterStateManager('', [])),
|
RosterManager(TestingRosterStateManager('', [])),
|
||||||
|
Loading…
Reference in New Issue
Block a user