2023-06-17 19:28:54 +00:00
|
|
|
import 'package:chalkdart/chalk.dart';
|
|
|
|
import 'package:cli_repl/cli_repl.dart';
|
2023-06-18 19:16:47 +00:00
|
|
|
import 'package:example_dart/arguments.dart';
|
2023-06-18 18:59:54 +00:00
|
|
|
import 'package:example_dart/socket.dart';
|
2023-06-17 19:28:54 +00:00
|
|
|
import 'package:logging/logging.dart';
|
|
|
|
import 'package:moxxmpp/moxxmpp.dart';
|
|
|
|
import 'package:omemo_dart/omemo_dart.dart' as omemo;
|
|
|
|
|
|
|
|
void main(List<String> args) async {
|
|
|
|
// Set up logging
|
|
|
|
Logger.root.level = Level.ALL;
|
|
|
|
Logger.root.onRecord.listen((record) {
|
|
|
|
// ignore: avoid_print
|
|
|
|
print(
|
|
|
|
'[${record.level.name}] (${record.loggerName}) ${record.time}: ${record.message}',
|
|
|
|
);
|
|
|
|
});
|
|
|
|
|
2023-06-18 19:16:47 +00:00
|
|
|
final parser = ArgumentParser()
|
|
|
|
..parser.addOption('to', help: 'The JID to send messages to');
|
|
|
|
final options = parser.handleArguments(args);
|
|
|
|
if (options == null) {
|
|
|
|
return;
|
2023-06-18 18:59:54 +00:00
|
|
|
}
|
|
|
|
|
2023-06-17 19:28:54 +00:00
|
|
|
// Connect
|
2023-06-18 19:16:47 +00:00
|
|
|
final jid = parser.jid;
|
2023-06-17 19:28:54 +00:00
|
|
|
final to = JID.fromString(options['to']! as String).toBare();
|
|
|
|
final connection = XmppConnection(
|
|
|
|
TestingReconnectionPolicy(),
|
|
|
|
AlwaysConnectedConnectivityManager(),
|
|
|
|
ClientToServerNegotiator(),
|
2023-10-04 20:15:24 +00:00
|
|
|
ExampleTCPSocketWrapper(parser.srvRecord, true),
|
2023-06-18 19:16:47 +00:00
|
|
|
)..connectionSettings = parser.connectionSettings;
|
2023-06-17 19:28:54 +00:00
|
|
|
|
|
|
|
// Generate OMEMO data
|
2023-06-17 21:51:52 +00:00
|
|
|
omemo.OmemoManager? oom;
|
|
|
|
final moxxmppOmemo = OmemoManager(
|
|
|
|
() async => oom!,
|
|
|
|
(toJid, _) async => toJid == to,
|
|
|
|
);
|
|
|
|
oom = omemo.OmemoManager(
|
2023-06-17 19:28:54 +00:00
|
|
|
await omemo.OmemoDevice.generateNewDevice(jid.toString(), opkAmount: 5),
|
|
|
|
omemo.BlindTrustBeforeVerificationTrustManager(),
|
|
|
|
moxxmppOmemo.sendEmptyMessageImpl,
|
|
|
|
moxxmppOmemo.fetchDeviceList,
|
|
|
|
moxxmppOmemo.fetchDeviceBundle,
|
|
|
|
moxxmppOmemo.subscribeToDeviceListImpl,
|
2023-06-17 21:51:52 +00:00
|
|
|
moxxmppOmemo.publishDeviceImpl,
|
2023-06-17 19:28:54 +00:00
|
|
|
);
|
2023-06-17 21:51:52 +00:00
|
|
|
final deviceId = await oom.getDeviceId();
|
2023-06-17 19:28:54 +00:00
|
|
|
Logger.root.info('Our device id: $deviceId');
|
|
|
|
|
|
|
|
// Register the managers and negotiators
|
|
|
|
await connection.registerManagers([
|
|
|
|
PresenceManager(),
|
|
|
|
DiscoManager([]),
|
|
|
|
PubSubManager(),
|
|
|
|
MessageManager(),
|
2023-06-18 18:59:54 +00:00
|
|
|
moxxmppOmemo,
|
2023-06-17 19:28:54 +00:00
|
|
|
]);
|
|
|
|
await connection.registerFeatureNegotiators([
|
|
|
|
SaslPlainNegotiator(),
|
|
|
|
ResourceBindingNegotiator(),
|
|
|
|
StartTlsNegotiator(),
|
|
|
|
SaslScramNegotiator(10, '', '', ScramHashType.sha1),
|
|
|
|
]);
|
|
|
|
|
|
|
|
// Set up event handlers
|
|
|
|
connection.asBroadcastStream().listen((event) {
|
|
|
|
if (event is MessageEvent) {
|
|
|
|
Logger.root.info(event.id);
|
|
|
|
Logger.root.info(event.extensions.keys.toList());
|
|
|
|
|
|
|
|
final body = event.encryptionError != null
|
2023-06-18 18:59:54 +00:00
|
|
|
? chalk.red('Failed to decrypt message: ${event.encryptionError}')
|
|
|
|
: chalk.green(event.get<MessageBodyData>()?.body ?? '');
|
|
|
|
print('[${event.from.toString()}] $body');
|
2023-06-17 19:28:54 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
|
|
|
// Connect
|
|
|
|
Logger.root.info('Connecting...');
|
2023-06-18 18:59:54 +00:00
|
|
|
final result =
|
|
|
|
await connection.connect(shouldReconnect: false, waitUntilLogin: true);
|
2023-06-17 19:28:54 +00:00
|
|
|
if (!result.isType<bool>()) {
|
|
|
|
Logger.root.severe('Authentication failed!');
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
Logger.root.info('Connected.');
|
|
|
|
|
|
|
|
// Publish our bundle
|
|
|
|
Logger.root.info('Publishing bundle');
|
2023-06-17 21:51:52 +00:00
|
|
|
final device = await oom.getDevice();
|
2023-06-17 19:28:54 +00:00
|
|
|
final omemoResult = await moxxmppOmemo.publishBundle(await device.toBundle());
|
|
|
|
if (!omemoResult.isType<bool>()) {
|
2023-06-18 18:59:54 +00:00
|
|
|
Logger.root.severe(
|
|
|
|
'Failed to publish OMEMO bundle: ${omemoResult.get<OmemoError>()}');
|
2023-06-17 19:28:54 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
final repl = Repl(prompt: '> ');
|
|
|
|
await for (final line in repl.runAsync()) {
|
2023-06-18 18:59:54 +00:00
|
|
|
await connection
|
|
|
|
.getManagerById<MessageManager>(messageManager)!
|
|
|
|
.sendMessage(
|
|
|
|
to,
|
|
|
|
TypedMap<StanzaHandlerExtension>.fromList([
|
|
|
|
MessageBodyData(line),
|
|
|
|
]),
|
|
|
|
);
|
2023-06-17 19:28:54 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Disconnect
|
|
|
|
await connection.disconnect();
|
|
|
|
}
|