Improve logging

This commit is contained in:
Christian Pauly 2020-08-06 09:35:02 +00:00
parent 6779ab6624
commit 6170c79fe1
29 changed files with 241 additions and 145 deletions

View File

@ -3,9 +3,11 @@ include: package:pedantic/analysis_options.yaml
linter: linter:
rules: rules:
- camel_case_types - camel_case_types
- avoid_print
analyzer: analyzer:
errors: errors:
todo: ignore todo: ignore
exclude: exclude:
- example/main.dart - example/main.dart
- lib/src/utils/logs.dart

View File

@ -18,6 +18,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
@ -84,10 +85,11 @@ class KeyManager {
} else { } else {
inboundGroupSession.create(content['session_key']); inboundGroupSession.create(content['session_key']);
} }
} catch (e) { } catch (e, s) {
inboundGroupSession.free(); inboundGroupSession.free();
print( Logs.error(
'[LibOlm] Could not create new InboundGroupSession: ' + e.toString()); '[LibOlm] Could not create new InboundGroupSession: ' + e.toString(),
s);
return; return;
} }
final newSession = SessionKey( final newSession = SessionKey(
@ -263,10 +265,11 @@ class KeyManager {
final outboundGroupSession = olm.OutboundGroupSession(); final outboundGroupSession = olm.OutboundGroupSession();
try { try {
outboundGroupSession.create(); outboundGroupSession.create();
} catch (e) { } catch (e, s) {
outboundGroupSession.free(); outboundGroupSession.free();
print('[LibOlm] Unable to create new outboundGroupSession: ' + Logs.error(
e.toString()); '[LibOlm] Unable to create new outboundGroupSession: ' + e.toString(),
s);
return null; return null;
} }
final rawSession = <String, dynamic>{ final rawSession = <String, dynamic>{
@ -289,10 +292,10 @@ class KeyManager {
await storeOutboundGroupSession(roomId, sess); await storeOutboundGroupSession(roomId, sess);
_outboundGroupSessions[roomId] = sess; _outboundGroupSessions[roomId] = sess;
} catch (e, s) { } catch (e, s) {
print( Logs.error(
'[LibOlm] Unable to send the session key to the participating devices: ' + '[LibOlm] Unable to send the session key to the participating devices: ' +
e.toString()); e.toString(),
print(s); s);
sess.dispose(); sess.dispose();
return null; return null;
} }
@ -365,8 +368,9 @@ class KeyManager {
try { try {
decrypted = json.decode(decryption.decrypt(sessionData['ephemeral'], decrypted = json.decode(decryption.decrypt(sessionData['ephemeral'],
sessionData['mac'], sessionData['ciphertext'])); sessionData['mac'], sessionData['ciphertext']));
} catch (err) { } catch (e, s) {
print('[LibOlm] Error decrypting room key: ' + err.toString()); Logs.error(
'[LibOlm] Error decrypting room key: ' + e.toString(), s);
} }
if (decrypted != null) { if (decrypted != null) {
decrypted['session_id'] = sessionId; decrypted['session_id'] = sessionId;
@ -408,9 +412,10 @@ class KeyManager {
try { try {
await loadSingleKey(room.id, sessionId); await loadSingleKey(room.id, sessionId);
} catch (err, stacktrace) { } catch (err, stacktrace) {
print('[KeyManager] Failed to access online key backup: ' + Logs.error(
err.toString()); '[KeyManager] Failed to access online key backup: ' +
print(stacktrace); err.toString(),
stacktrace);
} }
if (!hadPreviously && if (!hadPreviously &&
getInboundGroupSession(room.id, sessionId, senderKey) != null) { getInboundGroupSession(room.id, sessionId, senderKey) != null) {
@ -446,9 +451,11 @@ class KeyManager {
encrypted: false, encrypted: false,
toUsers: await room.requestParticipants()); toUsers: await room.requestParticipants());
outgoingShareRequests[request.requestId] = request; outgoingShareRequests[request.requestId] = request;
} catch (err) { } catch (e, s) {
print('[Key Manager] Sending key verification request failed: ' + Logs.error(
err.toString()); '[Key Manager] Sending key verification request failed: ' +
e.toString(),
s);
} }
} }
@ -460,27 +467,27 @@ class KeyManager {
} }
if (event.content['action'] == 'request') { if (event.content['action'] == 'request') {
// we are *receiving* a request // we are *receiving* a request
print('[KeyManager] Received key sharing request...'); Logs.info('[KeyManager] Received key sharing request...');
if (!event.content.containsKey('body')) { if (!event.content.containsKey('body')) {
print('[KeyManager] No body, doing nothing'); Logs.info('[KeyManager] No body, doing nothing');
return; // no body return; // no body
} }
if (!client.userDeviceKeys.containsKey(event.sender) || if (!client.userDeviceKeys.containsKey(event.sender) ||
!client.userDeviceKeys[event.sender].deviceKeys !client.userDeviceKeys[event.sender].deviceKeys
.containsKey(event.content['requesting_device_id'])) { .containsKey(event.content['requesting_device_id'])) {
print('[KeyManager] Device not found, doing nothing'); Logs.info('[KeyManager] Device not found, doing nothing');
return; // device not found return; // device not found
} }
final device = client.userDeviceKeys[event.sender] final device = client.userDeviceKeys[event.sender]
.deviceKeys[event.content['requesting_device_id']]; .deviceKeys[event.content['requesting_device_id']];
if (device.userId == client.userID && if (device.userId == client.userID &&
device.deviceId == client.deviceID) { device.deviceId == client.deviceID) {
print('[KeyManager] Request is by ourself, ignoring'); Logs.info('[KeyManager] Request is by ourself, ignoring');
return; // ignore requests by ourself return; // ignore requests by ourself
} }
final room = client.getRoomById(event.content['body']['room_id']); final room = client.getRoomById(event.content['body']['room_id']);
if (room == null) { if (room == null) {
print('[KeyManager] Unknown room, ignoring'); Logs.info('[KeyManager] Unknown room, ignoring');
return; // unknown room return; // unknown room
} }
final sessionId = event.content['body']['session_id']; final sessionId = event.content['body']['session_id'];
@ -488,7 +495,7 @@ class KeyManager {
// okay, let's see if we have this session at all // okay, let's see if we have this session at all
if ((await loadInboundGroupSession(room.id, sessionId, senderKey)) == if ((await loadInboundGroupSession(room.id, sessionId, senderKey)) ==
null) { null) {
print('[KeyManager] Unknown session, ignoring'); Logs.info('[KeyManager] Unknown session, ignoring');
return; // we don't have this session anyways return; // we don't have this session anyways
} }
final request = KeyManagerKeyShareRequest( final request = KeyManagerKeyShareRequest(
@ -499,7 +506,7 @@ class KeyManager {
senderKey: senderKey, senderKey: senderKey,
); );
if (incomingShareRequests.containsKey(request.requestId)) { if (incomingShareRequests.containsKey(request.requestId)) {
print('[KeyManager] Already processed this request, ignoring'); Logs.info('[KeyManager] Already processed this request, ignoring');
return; // we don't want to process one and the same request multiple times return; // we don't want to process one and the same request multiple times
} }
incomingShareRequests[request.requestId] = request; incomingShareRequests[request.requestId] = request;
@ -508,11 +515,12 @@ class KeyManager {
if (device.userId == client.userID && if (device.userId == client.userID &&
device.verified && device.verified &&
!device.blocked) { !device.blocked) {
print('[KeyManager] All checks out, forwarding key...'); Logs.info('[KeyManager] All checks out, forwarding key...');
// alright, we can forward the key // alright, we can forward the key
await roomKeyRequest.forwardKey(); await roomKeyRequest.forwardKey();
} else { } else {
print('[KeyManager] Asking client, if the key should be forwarded'); Logs.info(
'[KeyManager] Asking client, if the key should be forwarded');
client.onRoomKeyRequest client.onRoomKeyRequest
.add(roomKeyRequest); // let the client handle this .add(roomKeyRequest); // let the client handle this
} }

View File

@ -18,6 +18,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
import 'package:canonical_json/canonical_json.dart'; import 'package:canonical_json/canonical_json.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
@ -119,9 +120,9 @@ class OlmManager {
try { try {
olmutil.ed25519_verify(key, message, signature); olmutil.ed25519_verify(key, message, signature);
isValid = true; isValid = true;
} catch (e) { } catch (e, s) {
isValid = false; isValid = false;
print('[LibOlm] Signature check failed: ' + e.toString()); Logs.error('[LibOlm] Signature check failed: ' + e.toString(), s);
} finally { } finally {
olmutil.free(); olmutil.free();
} }
@ -408,10 +409,12 @@ class OlmManager {
lastReceived: lastReceived:
DateTime.now(), // we want to use a newly created session DateTime.now(), // we want to use a newly created session
)); ));
} catch (e) { } catch (e, s) {
session.free(); session.free();
print('[LibOlm] Could not create new outbound olm session: ' + Logs.error(
e.toString()); '[LibOlm] Could not create new outbound olm session: ' +
e.toString(),
s);
} }
} }
} }
@ -483,8 +486,9 @@ class OlmManager {
try { try {
data[device.userId][device.deviceId] = data[device.userId][device.deviceId] =
await encryptToDeviceMessagePayload(device, type, payload); await encryptToDeviceMessagePayload(device, type, payload);
} catch (e) { } catch (e, s) {
print('[LibOlm] Error encrypting to-device event: ' + e.toString()); Logs.error(
'[LibOlm] Error encrypting to-device event: ' + e.toString(), s);
continue; continue;
} }
} }

View File

@ -22,6 +22,7 @@ import 'dart:convert';
import 'package:encrypt/encrypt.dart'; import 'package:encrypt/encrypt.dart';
import 'package:crypto/crypto.dart'; import 'package:crypto/crypto.dart';
import 'package:base58check/base58.dart'; import 'package:base58check/base58.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:password_hash/password_hash.dart'; import 'package:password_hash/password_hash.dart';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
@ -253,14 +254,14 @@ class SSSS {
Future<void> request(String type, List<DeviceKeys> devices) async { Future<void> request(String type, List<DeviceKeys> devices) async {
// only send to own, verified devices // only send to own, verified devices
print('[SSSS] Requesting type ${type}...'); Logs.info('[SSSS] Requesting type ${type}...');
devices.removeWhere((DeviceKeys d) => devices.removeWhere((DeviceKeys d) =>
d.userId != client.userID || d.userId != client.userID ||
!d.verified || !d.verified ||
d.blocked || d.blocked ||
d.deviceId == client.deviceID); d.deviceId == client.deviceID);
if (devices.isEmpty) { if (devices.isEmpty) {
print('[SSSS] Warn: No devices'); Logs.warning('[SSSS] No devices');
return; return;
} }
final requestId = client.generateUniqueTransactionId(); final requestId = client.generateUniqueTransactionId();
@ -281,31 +282,32 @@ class SSSS {
Future<void> handleToDeviceEvent(ToDeviceEvent event) async { Future<void> handleToDeviceEvent(ToDeviceEvent event) async {
if (event.type == 'm.secret.request') { if (event.type == 'm.secret.request') {
// got a request to share a secret // got a request to share a secret
print('[SSSS] Received sharing request...'); Logs.info('[SSSS] Received sharing request...');
if (event.sender != client.userID || if (event.sender != client.userID ||
!client.userDeviceKeys.containsKey(client.userID)) { !client.userDeviceKeys.containsKey(client.userID)) {
print('[SSSS] Not sent by us'); Logs.info('[SSSS] Not sent by us');
return; // we aren't asking for it ourselves, so ignore return; // we aren't asking for it ourselves, so ignore
} }
if (event.content['action'] != 'request') { if (event.content['action'] != 'request') {
print('[SSSS] it is actually a cancelation'); Logs.info('[SSSS] it is actually a cancelation');
return; // not actually requesting, so ignore return; // not actually requesting, so ignore
} }
final device = client.userDeviceKeys[client.userID] final device = client.userDeviceKeys[client.userID]
.deviceKeys[event.content['requesting_device_id']]; .deviceKeys[event.content['requesting_device_id']];
if (device == null || !device.verified || device.blocked) { if (device == null || !device.verified || device.blocked) {
print('[SSSS] Unknown / unverified devices, ignoring'); Logs.info('[SSSS] Unknown / unverified devices, ignoring');
return; // nope....unknown or untrusted device return; // nope....unknown or untrusted device
} }
// alright, all seems fine...let's check if we actually have the secret they are asking for // alright, all seems fine...let's check if we actually have the secret they are asking for
final type = event.content['name']; final type = event.content['name'];
final secret = await getCached(type); final secret = await getCached(type);
if (secret == null) { if (secret == null) {
print('[SSSS] We don\'t have the secret for ${type} ourself, ignoring'); Logs.info(
'[SSSS] We don\'t have the secret for ${type} ourself, ignoring');
return; // seems like we don't have this, either return; // seems like we don't have this, either
} }
// okay, all checks out...time to share this secret! // okay, all checks out...time to share this secret!
print('[SSSS] Replying with secret for ${type}'); Logs.info('[SSSS] Replying with secret for ${type}');
await client.sendToDevice( await client.sendToDevice(
[device], [device],
'm.secret.send', 'm.secret.send',
@ -315,11 +317,11 @@ class SSSS {
}); });
} else if (event.type == 'm.secret.send') { } else if (event.type == 'm.secret.send') {
// receiving a secret we asked for // receiving a secret we asked for
print('[SSSS] Received shared secret...'); Logs.info('[SSSS] Received shared secret...');
if (event.sender != client.userID || if (event.sender != client.userID ||
!pendingShareRequests.containsKey(event.content['request_id']) || !pendingShareRequests.containsKey(event.content['request_id']) ||
event.encryptedContent == null) { event.encryptedContent == null) {
print('[SSSS] Not by us or unknown request'); Logs.info('[SSSS] Not by us or unknown request');
return; // we have no idea what we just received return; // we have no idea what we just received
} }
final request = pendingShareRequests[event.content['request_id']]; final request = pendingShareRequests[event.content['request_id']];
@ -330,26 +332,26 @@ class SSSS {
d.curve25519Key == event.encryptedContent['sender_key'], d.curve25519Key == event.encryptedContent['sender_key'],
orElse: () => null); orElse: () => null);
if (device == null) { if (device == null) {
print('[SSSS] Someone else replied?'); Logs.info('[SSSS] Someone else replied?');
return; // someone replied whom we didn't send the share request to return; // someone replied whom we didn't send the share request to
} }
final secret = event.content['secret']; final secret = event.content['secret'];
if (!(event.content['secret'] is String)) { if (!(event.content['secret'] is String)) {
print('[SSSS] Secret wasn\'t a string'); Logs.info('[SSSS] Secret wasn\'t a string');
return; // the secret wasn't a string....wut? return; // the secret wasn't a string....wut?
} }
// let's validate if the secret is, well, valid // let's validate if the secret is, well, valid
if (_validators.containsKey(request.type) && if (_validators.containsKey(request.type) &&
!(await _validators[request.type](secret))) { !(await _validators[request.type](secret))) {
print('[SSSS] The received secret was invalid'); Logs.info('[SSSS] The received secret was invalid');
return; // didn't pass the validator return; // didn't pass the validator
} }
pendingShareRequests.remove(request.requestId); pendingShareRequests.remove(request.requestId);
if (request.start.add(Duration(minutes: 15)).isBefore(DateTime.now())) { if (request.start.add(Duration(minutes: 15)).isBefore(DateTime.now())) {
print('[SSSS] Request is too far in the past'); Logs.info('[SSSS] Request is too far in the past');
return; // our request is more than 15min in the past...better not trust it anymore return; // our request is more than 15min in the past...better not trust it anymore
} }
print('[SSSS] Secret for type ${request.type} is ok, storing it'); Logs.info('[SSSS] Secret for type ${request.type} is ok, storing it');
if (client.database != null) { if (client.database != null) {
final keyId = keyIdFromType(request.type); final keyId = keyIdFromType(request.type);
if (keyId != null) { if (keyId != null) {

View File

@ -19,6 +19,7 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:canonical_json/canonical_json.dart'; import 'package:canonical_json/canonical_json.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:pedantic/pedantic.dart'; import 'package:pedantic/pedantic.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
@ -150,7 +151,7 @@ class KeyVerification {
} }
void dispose() { void dispose() {
print('[Key Verification] disposing object...'); Logs.info('[Key Verification] disposing object...');
method?.dispose(); method?.dispose();
} }
@ -202,7 +203,8 @@ class KeyVerification {
await Future.delayed(Duration(milliseconds: 50)); await Future.delayed(Duration(milliseconds: 50));
} }
_handlePayloadLock = true; _handlePayloadLock = true;
print('[Key Verification] Received type ${type}: ' + payload.toString()); Logs.info(
'[Key Verification] Received type ${type}: ' + payload.toString());
try { try {
var thisLastStep = lastStep; var thisLastStep = lastStep;
switch (type) { switch (type) {
@ -297,7 +299,7 @@ class KeyVerification {
startPaylaod = payload; startPaylaod = payload;
setState(KeyVerificationState.askAccept); setState(KeyVerificationState.askAccept);
} else { } else {
print('handling start in method.....'); Logs.info('handling start in method.....');
await method.handlePayload(type, payload); await method.handlePayload(type, payload);
} }
break; break;
@ -322,8 +324,8 @@ class KeyVerification {
lastStep = type; lastStep = type;
} }
} catch (err, stacktrace) { } catch (err, stacktrace) {
print('[Key Verification] An error occured: ' + err.toString()); Logs.error(
print(stacktrace); '[Key Verification] An error occured: ' + err.toString(), stacktrace);
await cancel('m.invalid_message'); await cancel('m.invalid_message');
} finally { } finally {
_handlePayloadLock = false; _handlePayloadLock = false;
@ -550,9 +552,10 @@ class KeyVerification {
Future<void> send(String type, Map<String, dynamic> payload) async { Future<void> send(String type, Map<String, dynamic> payload) async {
makePayload(payload); makePayload(payload);
print('[Key Verification] Sending type ${type}: ' + payload.toString()); Logs.info('[Key Verification] Sending type ${type}: ' + payload.toString());
if (room != null) { if (room != null) {
print('[Key Verification] Sending to ${userId} in room ${room.id}...'); Logs.info(
'[Key Verification] Sending to ${userId} in room ${room.id}...');
if (['m.key.verification.request'].contains(type)) { if (['m.key.verification.request'].contains(type)) {
payload['msgtype'] = type; payload['msgtype'] = type;
payload['to'] = userId; payload['to'] = userId;
@ -566,7 +569,8 @@ class KeyVerification {
encryption.keyVerificationManager.addRequest(this); encryption.keyVerificationManager.addRequest(this);
} }
} else { } else {
print('[Key Verification] Sending to ${userId} device ${deviceId}...'); Logs.info(
'[Key Verification] Sending to ${userId} device ${deviceId}...');
await client.sendToDevice( await client.sendToDevice(
[client.userDeviceKeys[userId].deviceKeys[deviceId]], type, payload); [client.userDeviceKeys[userId].deviceKeys[deviceId]], type, payload);
} }
@ -693,8 +697,8 @@ class _KeyVerificationMethodSas extends _KeyVerificationMethod {
break; break;
} }
} catch (err, stacktrace) { } catch (err, stacktrace) {
print('[Key Verification SAS] An error occured: ' + err.toString()); Logs.error('[Key Verification SAS] An error occured: ' + err.toString(),
print(stacktrace); stacktrace);
if (request.deviceId != null) { if (request.deviceId != null) {
await request.cancel('m.invalid_message'); await request.cancel('m.invalid_message');
} }

View File

@ -16,6 +16,7 @@
* along with this program. If not, see <https://www.gnu.org/licenses/>. * along with this program. If not, see <https://www.gnu.org/licenses/>.
*/ */
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
import '../../src/database/database.dart' show DbOlmSessions; import '../../src/database/database.dart' show DbOlmSessions;
@ -46,8 +47,8 @@ class OlmSession {
lastReceived = lastReceived =
dbEntry.lastReceived ?? DateTime.fromMillisecondsSinceEpoch(0); dbEntry.lastReceived ?? DateTime.fromMillisecondsSinceEpoch(0);
assert(sessionId == session.session_id()); assert(sessionId == session.session_id());
} catch (e) { } catch (e, s) {
print('[LibOlm] Could not unpickle olm session: ' + e.toString()); Logs.error('[LibOlm] Could not unpickle olm session: ' + e.toString(), s);
dispose(); dispose();
} }
} }

View File

@ -18,6 +18,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
import '../../src/database/database.dart' show DbOutboundGroupSession; import '../../src/database/database.dart' show DbOutboundGroupSession;
@ -44,10 +45,11 @@ class OutboundGroupSession {
devices = List<String>.from(json.decode(dbEntry.deviceIds)); devices = List<String>.from(json.decode(dbEntry.deviceIds));
creationTime = dbEntry.creationTime; creationTime = dbEntry.creationTime;
sentMessages = dbEntry.sentMessages; sentMessages = dbEntry.sentMessages;
} catch (e) { } catch (e, s) {
dispose(); dispose();
print( Logs.error(
'[LibOlm] Unable to unpickle outboundGroupSession: ' + e.toString()); '[LibOlm] Unable to unpickle outboundGroupSession: ' + e.toString(),
s);
} }
} }

View File

@ -18,6 +18,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
@ -48,9 +49,11 @@ class SessionKey {
inboundGroupSession = olm.InboundGroupSession(); inboundGroupSession = olm.InboundGroupSession();
try { try {
inboundGroupSession.unpickle(key, dbEntry.pickle); inboundGroupSession.unpickle(key, dbEntry.pickle);
} catch (e) { } catch (e, s) {
dispose(); dispose();
print('[LibOlm] Unable to unpickle inboundGroupSession: ' + e.toString()); Logs.error(
'[LibOlm] Unable to unpickle inboundGroupSession: ' + e.toString(),
s);
} }
} }

View File

@ -25,6 +25,7 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/room.dart'; import 'package:famedlysdk/src/room.dart';
import 'package:famedlysdk/src/utils/device_keys_list.dart'; import 'package:famedlysdk/src/utils/device_keys_list.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:famedlysdk/src/utils/matrix_file.dart'; import 'package:famedlysdk/src/utils/matrix_file.dart';
import 'package:famedlysdk/src/utils/to_device_event.dart'; import 'package:famedlysdk/src/utils/to_device_event.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -147,7 +148,7 @@ class Client {
/// Warning! This endpoint is for testing only! /// Warning! This endpoint is for testing only!
set rooms(List<Room> newList) { set rooms(List<Room> newList) {
print('Warning! This endpoint is for testing only!'); Logs.warning('Warning! This endpoint is for testing only!');
_rooms = newList; _rooms = newList;
} }
@ -368,8 +369,8 @@ class Client {
Future<void> logout() async { Future<void> logout() async {
try { try {
await api.logout(); await api.logout();
} catch (exception) { } catch (e, s) {
print(exception); Logs.error(e, s);
rethrow; rethrow;
} finally { } finally {
await clear(); await clear();
@ -664,6 +665,9 @@ class Client {
} }
onLoginStateChanged.add(LoginState.logged); onLoginStateChanged.add(LoginState.logged);
Logs.success(
'Successfully connected as ${userID.localpart} with ${api.homeserver.toString()}',
);
return _sync(); return _sync();
} }
@ -734,8 +738,7 @@ class Client {
if (isLogged() == false || _disposed) { if (isLogged() == false || _disposed) {
return; return;
} }
print('Error during processing events: ' + e.toString()); Logs.error('Error during processing events: ' + e.toString(), s);
print(s);
onSyncError.add(SyncError( onSyncError.add(SyncError(
exception: e is Exception ? e : Exception(e), stackTrace: s)); exception: e is Exception ? e : Exception(e), stackTrace: s));
await Future.delayed(Duration(seconds: syncErrorTimeoutSec), _sync); await Future.delayed(Duration(seconds: syncErrorTimeoutSec), _sync);
@ -814,10 +817,10 @@ class Client {
try { try {
toDeviceEvent = await encryption.decryptToDeviceEvent(toDeviceEvent); toDeviceEvent = await encryption.decryptToDeviceEvent(toDeviceEvent);
} catch (e, s) { } catch (e, s) {
print( Logs.error(
'[LibOlm] Could not decrypt to device event from ${toDeviceEvent.sender} with content: ${toDeviceEvent.content}'); '[LibOlm] Could not decrypt to device event from ${toDeviceEvent.sender} with content: ${toDeviceEvent.content}\n${e.toString()}',
print(e); s);
print(s);
onOlmError.add( onOlmError.add(
ToDeviceEventDecryptionError( ToDeviceEventDecryptionError(
exception: e is Exception ? e : Exception(e), exception: e is Exception ? e : Exception(e),
@ -1161,8 +1164,8 @@ class Client {
userIds.add(user.id); userIds.add(user.id);
} }
} }
} catch (err) { } catch (e, s) {
print('[E2EE] Failed to fetch participants: ' + err.toString()); Logs.error('[E2EE] Failed to fetch participants: ' + e.toString(), s);
} }
} }
} }
@ -1338,8 +1341,9 @@ class Client {
} }
}); });
} }
} catch (e) { } catch (e, s) {
print('[LibOlm] Unable to update user device keys: ' + e.toString()); Logs.error(
'[LibOlm] Unable to update user device keys: ' + e.toString(), s);
} }
} }

View File

@ -1,3 +1,4 @@
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:moor/moor.dart'; import 'package:moor/moor.dart';
import 'dart:convert'; import 'dart:convert';
@ -66,7 +67,7 @@ class Database extends _$Database {
if (executor.dialect == SqlDialect.sqlite) { if (executor.dialect == SqlDialect.sqlite) {
final ret = await customSelect('PRAGMA journal_mode=WAL').get(); final ret = await customSelect('PRAGMA journal_mode=WAL').get();
if (ret.isNotEmpty) { if (ret.isNotEmpty) {
print('[Moor] Switched database to mode ' + Logs.info('[Moor] Switched database to mode ' +
ret.first.data['journal_mode'].toString()); ret.first.data['journal_mode'].toString());
} }
} }
@ -113,8 +114,9 @@ class Database extends _$Database {
var session = olm.Session(); var session = olm.Session();
session.unpickle(userId, row.pickle); session.unpickle(userId, row.pickle);
res[row.identityKey].add(session); res[row.identityKey].add(session);
} catch (e) { } catch (e, s) {
print('[LibOlm] Could not unpickle olm session: ' + e.toString()); Logs.error(
'[LibOlm] Could not unpickle olm session: ' + e.toString(), s);
} }
} }
return res; return res;

View File

@ -20,6 +20,7 @@ import 'dart:convert';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/encryption.dart'; import 'package:famedlysdk/encryption.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:famedlysdk/src/utils/receipt.dart'; import 'package:famedlysdk/src/utils/receipt.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; import 'package:matrix_file_e2ee/matrix_file_e2ee.dart';
@ -96,12 +97,18 @@ class Event extends MatrixEvent {
this.senderId = senderId; this.senderId = senderId;
this.unsigned = unsigned; this.unsigned = unsigned;
// synapse unfortunatley isn't following the spec and tosses the prev_content // synapse unfortunatley isn't following the spec and tosses the prev_content
// into the unsigned block // into the unsigned block.
this.prevContent = prevContent != null && prevContent.isNotEmpty // Currently we are facing a very strange bug in web which is impossible to debug.
? prevContent // It may be because of this line so we put this in try-catch until we can fix it.
: (unsigned != null && unsigned['prev_content'] is Map) try {
? unsigned['prev_content'] this.prevContent = (prevContent != null && prevContent.isNotEmpty)
: null; ? prevContent
: (unsigned != null && unsigned['prev_content'] is Map)
? unsigned['prev_content']
: null;
} catch (e, s) {
Logs.error('Event constructor crashed: ${e.toString()}', s);
}
this.stateKey = stateKey; this.stateKey = stateKey;
this.originServerTs = originServerTs; this.originServerTs = originServerTs;
} }

View File

@ -23,6 +23,7 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/client.dart'; import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/event.dart'; import 'package:famedlysdk/src/event.dart';
import 'package:famedlysdk/src/utils/event_update.dart'; import 'package:famedlysdk/src/utils/event_update.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:famedlysdk/src/utils/room_update.dart'; import 'package:famedlysdk/src/utils/room_update.dart';
import 'package:famedlysdk/src/utils/matrix_file.dart'; import 'package:famedlysdk/src/utils/matrix_file.dart';
import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; import 'package:matrix_file_e2ee/matrix_file_e2ee.dart';
@ -136,8 +137,8 @@ class Room {
if (state.type == EventTypes.Encrypted && client.encryptionEnabled) { if (state.type == EventTypes.Encrypted && client.encryptionEnabled) {
try { try {
state = client.encryption.decryptRoomEventSync(id, state); state = client.encryption.decryptRoomEventSync(id, state);
} catch (e) { } catch (e, s) {
print('[LibOlm] Could not decrypt room state: ' + e.toString()); Logs.error('[LibOlm] Could not decrypt room state: ' + e.toString(), s);
} }
} }
if (!(state.stateKey is String) && if (!(state.stateKey is String) &&
@ -715,8 +716,9 @@ class Room {
syncUpdate.rooms.join.values.first.timeline.events.first.eventId = res; syncUpdate.rooms.join.values.first.timeline.events.first.eventId = res;
await client.handleSync(syncUpdate); await client.handleSync(syncUpdate);
return res; return res;
} catch (exception) { } catch (e, s) {
print('[Client] Error while sending: ' + exception.toString()); Logs.warning(
'[Client] Problem while sending message: ' + e.toString(), s);
syncUpdate.rooms.join.values.first.timeline.events.first syncUpdate.rooms.join.values.first.timeline.events.first
.unsigned[MessageSendingStatusKey] = -1; .unsigned[MessageSendingStatusKey] = -1;
await client.handleSync(syncUpdate); await client.handleSync(syncUpdate);

View File

@ -19,6 +19,7 @@
import 'dart:async'; import 'dart:async';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'event.dart'; import 'event.dart';
import 'room.dart'; import 'room.dart';
@ -263,8 +264,7 @@ class Timeline {
} }
sortAndUpdate(); sortAndUpdate();
} catch (e, s) { } catch (e, s) {
print('[WARNING] (_handleEventUpdate) ${e.toString()}'); Logs.warning('Handle event update failed: ${e.toString()}', s);
print(s);
} }
} }

View File

@ -18,6 +18,7 @@
import '../../famedlysdk.dart'; import '../../famedlysdk.dart';
import '../../matrix_api.dart'; import '../../matrix_api.dart';
import 'logs.dart';
/// Represents a new event (e.g. a message in a room) or an update for an /// Represents a new event (e.g. a message in a room) or an update for an
/// already known event. /// already known event.
@ -57,8 +58,8 @@ class EventUpdate {
content: decrpytedEvent.toJson(), content: decrpytedEvent.toJson(),
sortOrder: sortOrder, sortOrder: sortOrder,
); );
} catch (e) { } catch (e, s) {
print('[LibOlm] Could not decrypt megolm event: ' + e.toString()); Logs.error('[LibOlm] Could not decrypt megolm event: ' + e.toString(), s);
return this; return this;
} }
} }

30
lib/src/utils/logs.dart Normal file
View File

@ -0,0 +1,30 @@
import 'package:ansicolor/ansicolor.dart';
abstract class Logs {
static final AnsiPen _infoPen = AnsiPen()..blue();
static final AnsiPen _warningPen = AnsiPen()..yellow();
static final AnsiPen _successPen = AnsiPen()..green();
static final AnsiPen _errorPen = AnsiPen()..red();
static const String _prefixText = '[Famedly Matrix SDK] ';
static void info(dynamic info) => print(
_prefixText + _infoPen(info.toString()),
);
static void success(dynamic obj, [dynamic stackTrace]) => print(
_prefixText + _successPen(obj.toString()),
);
static void warning(dynamic warning, [dynamic stackTrace]) => print(
_prefixText +
_warningPen(warning.toString()) +
(stackTrace != null ? '\n${stackTrace.toString()}' : ''),
);
static void error(dynamic obj, [dynamic stackTrace]) => print(
_prefixText +
_errorPen(obj.toString()) +
(stackTrace != null ? '\n${stackTrace.toString()}' : ''),
);
}

View File

@ -22,6 +22,13 @@ packages:
url: "https://pub.dartlang.org" url: "https://pub.dartlang.org"
source: hosted source: hosted
version: "0.2.2" version: "0.2.2"
ansicolor:
dependency: "direct main"
description:
name: ansicolor
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.2"
args: args:
dependency: transitive dependency: transitive
description: description:

View File

@ -21,6 +21,7 @@ dependencies:
password_hash: ^2.0.0 password_hash: ^2.0.0
olm: ^1.2.1 olm: ^1.2.1
matrix_file_e2ee: ^1.0.4 matrix_file_e2ee: ^1.0.4
ansicolor: ^1.0.2
dev_dependencies: dev_dependencies:
test: ^1.0.0 test: ^1.0.0

View File

@ -23,6 +23,7 @@ import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/client.dart'; import 'package:famedlysdk/src/client.dart';
import 'package:famedlysdk/src/utils/event_update.dart'; import 'package:famedlysdk/src/utils/event_update.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:famedlysdk/src/utils/room_update.dart'; import 'package:famedlysdk/src/utils/room_update.dart';
import 'package:famedlysdk/src/utils/matrix_file.dart'; import 'package:famedlysdk/src/utils/matrix_file.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -59,9 +60,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
test('Login', () async { test('Login', () async {
var presenceCounter = 0; var presenceCounter = 0;

View File

@ -19,6 +19,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -74,9 +75,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.error('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -19,6 +19,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -33,9 +34,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -17,6 +17,7 @@
*/ */
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -30,9 +31,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -17,6 +17,7 @@
*/ */
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -35,9 +36,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -17,6 +17,7 @@
*/ */
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -30,9 +31,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -18,6 +18,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -45,9 +46,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;
@ -106,7 +107,7 @@ void main() {
'requesting_device_id': 'OTHERDEVICE', 'requesting_device_id': 'OTHERDEVICE',
}); });
await matrix.encryption.keyManager.handleToDeviceEvent(event); await matrix.encryption.keyManager.handleToDeviceEvent(event);
print(FakeMatrixApi.calledEndpoints.keys.toString()); Logs.info(FakeMatrixApi.calledEndpoints.keys.toString());
expect( expect(
FakeMatrixApi.calledEndpoints.keys.any( FakeMatrixApi.calledEndpoints.keys.any(
(k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')),

View File

@ -20,6 +20,7 @@ import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/encryption.dart'; import 'package:famedlysdk/encryption.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -67,9 +68,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -18,6 +18,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -32,9 +33,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -17,6 +17,7 @@
*/ */
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -30,9 +31,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -22,6 +22,7 @@ import 'dart:convert';
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/encryption.dart'; import 'package:famedlysdk/encryption.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:encrypt/encrypt.dart'; import 'package:encrypt/encrypt.dart';
import 'package:olm/olm.dart' as olm; import 'package:olm/olm.dart' as olm;
@ -37,9 +38,9 @@ void main() {
olm.Account(); olm.Account();
} catch (_) { } catch (_) {
olmEnabled = false; olmEnabled = false;
print('[LibOlm] Failed to load LibOlm: ' + _.toString()); Logs.warning('[LibOlm] Failed to load LibOlm: ' + _.toString());
} }
print('[LibOlm] Enabled: $olmEnabled'); Logs.success('[LibOlm] Enabled: $olmEnabled');
if (!olmEnabled) return; if (!olmEnabled) return;

View File

@ -1,5 +1,6 @@
import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/famedlysdk.dart';
import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/matrix_api.dart';
import 'package:famedlysdk/src/utils/logs.dart';
import '../test/fake_database.dart'; import '../test/fake_database.dart';
void main() => test(); void main() => test();
@ -17,21 +18,21 @@ const String testMessage5 = 'Hello earth';
const String testMessage6 = 'Hello mars'; const String testMessage6 = 'Hello mars';
void test() async { void test() async {
print('++++ Login $testUserA ++++'); Logs.success('++++ Login $testUserA ++++');
var testClientA = Client('TestClientA'); var testClientA = Client('TestClientA');
testClientA.database = getDatabase(); testClientA.database = getDatabase();
await testClientA.checkServer(homeserver); await testClientA.checkServer(homeserver);
await testClientA.login(testUserA, testPasswordA); await testClientA.login(testUserA, testPasswordA);
assert(testClientA.encryptionEnabled); assert(testClientA.encryptionEnabled);
print('++++ Login $testUserB ++++'); Logs.success('++++ Login $testUserB ++++');
var testClientB = Client('TestClientB'); var testClientB = Client('TestClientB');
testClientB.database = getDatabase(); testClientB.database = getDatabase();
await testClientB.checkServer(homeserver); await testClientB.checkServer(homeserver);
await testClientB.login(testUserB, testPasswordA); await testClientB.login(testUserB, testPasswordA);
assert(testClientB.encryptionEnabled); assert(testClientB.encryptionEnabled);
print('++++ ($testUserA) Leave all rooms ++++'); Logs.success('++++ ($testUserA) Leave all rooms ++++');
while (testClientA.rooms.isNotEmpty) { while (testClientA.rooms.isNotEmpty) {
var room = testClientA.rooms.first; var room = testClientA.rooms.first;
if (room.canonicalAlias?.isNotEmpty ?? false) { if (room.canonicalAlias?.isNotEmpty ?? false) {
@ -43,7 +44,7 @@ void test() async {
} catch (_) {} } catch (_) {}
} }
print('++++ ($testUserB) Leave all rooms ++++'); Logs.success('++++ ($testUserB) Leave all rooms ++++');
for (var i = 0; i < 3; i++) { for (var i = 0; i < 3; i++) {
if (testClientB.rooms.isNotEmpty) { if (testClientB.rooms.isNotEmpty) {
var room = testClientB.rooms.first; var room = testClientB.rooms.first;
@ -54,7 +55,7 @@ void test() async {
} }
} }
print('++++ Check if own olm device is verified by default ++++'); Logs.success('++++ Check if own olm device is verified by default ++++');
assert(testClientA.userDeviceKeys.containsKey(testUserA)); assert(testClientA.userDeviceKeys.containsKey(testUserA));
assert(testClientA.userDeviceKeys[testUserA].deviceKeys assert(testClientA.userDeviceKeys[testUserA].deviceKeys
.containsKey(testClientA.deviceID)); .containsKey(testClientA.deviceID));
@ -70,20 +71,20 @@ void test() async {
assert(!testClientB assert(!testClientB
.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].blocked); .userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].blocked);
print('++++ ($testUserA) Create room and invite $testUserB ++++'); Logs.success('++++ ($testUserA) Create room and invite $testUserB ++++');
await testClientA.api.createRoom(invite: [testUserB]); await testClientA.api.createRoom(invite: [testUserB]);
await Future.delayed(Duration(seconds: 1)); await Future.delayed(Duration(seconds: 1));
var room = testClientA.rooms.first; var room = testClientA.rooms.first;
assert(room != null); assert(room != null);
final roomId = room.id; final roomId = room.id;
print('++++ ($testUserB) Join room ++++'); Logs.success('++++ ($testUserB) Join room ++++');
var inviteRoom = testClientB.getRoomById(roomId); var inviteRoom = testClientB.getRoomById(roomId);
await inviteRoom.join(); await inviteRoom.join();
await Future.delayed(Duration(seconds: 1)); await Future.delayed(Duration(seconds: 1));
assert(inviteRoom.membership == Membership.join); assert(inviteRoom.membership == Membership.join);
print('++++ ($testUserA) Enable encryption ++++'); Logs.success('++++ ($testUserA) Enable encryption ++++');
assert(room.encrypted == false); assert(room.encrypted == false);
await room.enableEncryption(); await room.enableEncryption();
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
@ -91,7 +92,7 @@ void test() async {
assert(room.client.encryption.keyManager.getOutboundGroupSession(room.id) == assert(room.client.encryption.keyManager.getOutboundGroupSession(room.id) ==
null); null);
print('++++ ($testUserA) Check known olm devices ++++'); Logs.success('++++ ($testUserA) Check known olm devices ++++');
assert(testClientA.userDeviceKeys.containsKey(testUserB)); assert(testClientA.userDeviceKeys.containsKey(testUserB));
assert(testClientA.userDeviceKeys[testUserB].deviceKeys assert(testClientA.userDeviceKeys[testUserB].deviceKeys
.containsKey(testClientB.deviceID)); .containsKey(testClientB.deviceID));
@ -109,7 +110,7 @@ void test() async {
await testClientA.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID] await testClientA.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID]
.setVerified(true); .setVerified(true);
print('++++ Check if own olm device is verified by default ++++'); Logs.success('++++ Check if own olm device is verified by default ++++');
assert(testClientA.userDeviceKeys.containsKey(testUserA)); assert(testClientA.userDeviceKeys.containsKey(testUserA));
assert(testClientA.userDeviceKeys[testUserA].deviceKeys assert(testClientA.userDeviceKeys[testUserA].deviceKeys
.containsKey(testClientA.deviceID)); .containsKey(testClientA.deviceID));
@ -121,7 +122,7 @@ void test() async {
assert(testClientB assert(testClientB
.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].verified); .userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].verified);
print("++++ ($testUserA) Send encrypted message: '$testMessage' ++++"); Logs.success("++++ ($testUserA) Send encrypted message: '$testMessage' ++++");
await room.sendTextEvent(testMessage); await room.sendTextEvent(testMessage);
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(room.client.encryption.keyManager.getOutboundGroupSession(room.id) != assert(room.client.encryption.keyManager.getOutboundGroupSession(room.id) !=
@ -148,10 +149,11 @@ void test() async {
null); null);
assert(room.lastMessage == testMessage); assert(room.lastMessage == testMessage);
assert(inviteRoom.lastMessage == testMessage); assert(inviteRoom.lastMessage == testMessage);
print( Logs.success(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print("++++ ($testUserA) Send again encrypted message: '$testMessage2' ++++"); Logs.success(
"++++ ($testUserA) Send again encrypted message: '$testMessage2' ++++");
await room.sendTextEvent(testMessage2); await room.sendTextEvent(testMessage2);
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(testClientA assert(testClientA
@ -175,10 +177,11 @@ void test() async {
null); null);
assert(room.lastMessage == testMessage2); assert(room.lastMessage == testMessage2);
assert(inviteRoom.lastMessage == testMessage2); assert(inviteRoom.lastMessage == testMessage2);
print( Logs.success(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print("++++ ($testUserB) Send again encrypted message: '$testMessage3' ++++"); Logs.success(
"++++ ($testUserB) Send again encrypted message: '$testMessage3' ++++");
await inviteRoom.sendTextEvent(testMessage3); await inviteRoom.sendTextEvent(testMessage3);
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(testClientA assert(testClientA
@ -208,16 +211,17 @@ void test() async {
null); null);
assert(inviteRoom.lastMessage == testMessage3); assert(inviteRoom.lastMessage == testMessage3);
assert(room.lastMessage == testMessage3); assert(room.lastMessage == testMessage3);
print( Logs.success(
"++++ ($testUserA) Received decrypted message: '${room.lastMessage}' ++++"); "++++ ($testUserA) Received decrypted message: '${room.lastMessage}' ++++");
print('++++ Login $testUserB in another client ++++'); Logs.success('++++ Login $testUserB in another client ++++');
var testClientC = Client('TestClientC', database: getDatabase()); var testClientC = Client('TestClientC', database: getDatabase());
await testClientC.checkServer(homeserver); await testClientC.checkServer(homeserver);
await testClientC.login(testUserB, testPasswordA); await testClientC.login(testUserB, testPasswordA);
await Future.delayed(Duration(seconds: 3)); await Future.delayed(Duration(seconds: 3));
print("++++ ($testUserA) Send again encrypted message: '$testMessage4' ++++"); Logs.success(
"++++ ($testUserA) Send again encrypted message: '$testMessage4' ++++");
await room.sendTextEvent(testMessage4); await room.sendTextEvent(testMessage4);
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(testClientA assert(testClientA
@ -254,16 +258,17 @@ void test() async {
null); null);
assert(room.lastMessage == testMessage4); assert(room.lastMessage == testMessage4);
assert(inviteRoom.lastMessage == testMessage4); assert(inviteRoom.lastMessage == testMessage4);
print( Logs.success(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
print('++++ Logout $testUserB another client ++++'); Logs.success('++++ Logout $testUserB another client ++++');
await testClientC.dispose(); await testClientC.dispose();
await testClientC.logout(); await testClientC.logout();
testClientC = null; testClientC = null;
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
print("++++ ($testUserA) Send again encrypted message: '$testMessage6' ++++"); Logs.success(
"++++ ($testUserA) Send again encrypted message: '$testMessage6' ++++");
await room.sendTextEvent(testMessage6); await room.sendTextEvent(testMessage6);
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(testClientA assert(testClientA
@ -290,10 +295,10 @@ void test() async {
null); null);
assert(room.lastMessage == testMessage6); assert(room.lastMessage == testMessage6);
assert(inviteRoom.lastMessage == testMessage6); assert(inviteRoom.lastMessage == testMessage6);
print( Logs.success(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");
/* print('++++ ($testUserA) Restore user ++++'); /* Logs.success('++++ ($testUserA) Restore user ++++');
await testClientA.dispose(); await testClientA.dispose();
testClientA = null; testClientA = null;
testClientA = Client( testClientA = Client(
@ -320,7 +325,7 @@ void test() async {
assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey].first.session_id() == assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey].first.session_id() ==
testClientB.encryption.olmManager.olmSessions[testClientA.identityKey].first.session_id()); testClientB.encryption.olmManager.olmSessions[testClientA.identityKey].first.session_id());
print("++++ ($testUserA) Send again encrypted message: '$testMessage5' ++++"); Logs.success("++++ ($testUserA) Send again encrypted message: '$testMessage5' ++++");
await restoredRoom.sendTextEvent(testMessage5); await restoredRoom.sendTextEvent(testMessage5);
await Future.delayed(Duration(seconds: 5)); await Future.delayed(Duration(seconds: 5));
assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey].length == 1); assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey].length == 1);
@ -330,10 +335,10 @@ void test() async {
assert(restoredRoom.lastMessage == testMessage5); assert(restoredRoom.lastMessage == testMessage5);
assert(inviteRoom.lastMessage == testMessage5); assert(inviteRoom.lastMessage == testMessage5);
assert(testClientB.getRoomById(roomId).lastMessage == testMessage5); assert(testClientB.getRoomById(roomId).lastMessage == testMessage5);
print( Logs.success(
"++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");*/ "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");*/
print('++++ Logout $testUserA and $testUserB ++++'); Logs.success('++++ Logout $testUserA and $testUserB ++++');
await room.leave(); await room.leave();
await room.forget(); await room.forget();
await inviteRoom.leave(); await inviteRoom.leave();