diff --git a/analysis_options.yaml b/analysis_options.yaml index 93361f5..a3efac9 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -3,9 +3,11 @@ include: package:pedantic/analysis_options.yaml linter: rules: - camel_case_types + - avoid_print analyzer: errors: todo: ignore exclude: - - example/main.dart \ No newline at end of file + - example/main.dart + - lib/src/utils/logs.dart \ No newline at end of file diff --git a/lib/encryption/key_manager.dart b/lib/encryption/key_manager.dart index b6bc269..a2a3e55 100644 --- a/lib/encryption/key_manager.dart +++ b/lib/encryption/key_manager.dart @@ -18,6 +18,7 @@ import 'dart:convert'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:pedantic/pedantic.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; @@ -84,10 +85,11 @@ class KeyManager { } else { inboundGroupSession.create(content['session_key']); } - } catch (e) { + } catch (e, s) { inboundGroupSession.free(); - print( - '[LibOlm] Could not create new InboundGroupSession: ' + e.toString()); + Logs.error( + '[LibOlm] Could not create new InboundGroupSession: ' + e.toString(), + s); return; } final newSession = SessionKey( @@ -263,10 +265,11 @@ class KeyManager { final outboundGroupSession = olm.OutboundGroupSession(); try { outboundGroupSession.create(); - } catch (e) { + } catch (e, s) { outboundGroupSession.free(); - print('[LibOlm] Unable to create new outboundGroupSession: ' + - e.toString()); + Logs.error( + '[LibOlm] Unable to create new outboundGroupSession: ' + e.toString(), + s); return null; } final rawSession = { @@ -289,10 +292,10 @@ class KeyManager { await storeOutboundGroupSession(roomId, sess); _outboundGroupSessions[roomId] = sess; } catch (e, s) { - print( + Logs.error( '[LibOlm] Unable to send the session key to the participating devices: ' + - e.toString()); - print(s); + e.toString(), + s); sess.dispose(); return null; } @@ -365,8 +368,9 @@ class KeyManager { try { decrypted = json.decode(decryption.decrypt(sessionData['ephemeral'], sessionData['mac'], sessionData['ciphertext'])); - } catch (err) { - print('[LibOlm] Error decrypting room key: ' + err.toString()); + } catch (e, s) { + Logs.error( + '[LibOlm] Error decrypting room key: ' + e.toString(), s); } if (decrypted != null) { decrypted['session_id'] = sessionId; @@ -408,9 +412,10 @@ class KeyManager { try { await loadSingleKey(room.id, sessionId); } catch (err, stacktrace) { - print('[KeyManager] Failed to access online key backup: ' + - err.toString()); - print(stacktrace); + Logs.error( + '[KeyManager] Failed to access online key backup: ' + + err.toString(), + stacktrace); } if (!hadPreviously && getInboundGroupSession(room.id, sessionId, senderKey) != null) { @@ -446,9 +451,11 @@ class KeyManager { encrypted: false, toUsers: await room.requestParticipants()); outgoingShareRequests[request.requestId] = request; - } catch (err) { - print('[Key Manager] Sending key verification request failed: ' + - err.toString()); + } catch (e, s) { + Logs.error( + '[Key Manager] Sending key verification request failed: ' + + e.toString(), + s); } } @@ -460,27 +467,27 @@ class KeyManager { } if (event.content['action'] == 'request') { // we are *receiving* a request - print('[KeyManager] Received key sharing request...'); + Logs.info('[KeyManager] Received key sharing request...'); if (!event.content.containsKey('body')) { - print('[KeyManager] No body, doing nothing'); + Logs.info('[KeyManager] No body, doing nothing'); return; // no body } if (!client.userDeviceKeys.containsKey(event.sender) || !client.userDeviceKeys[event.sender].deviceKeys .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 } final device = client.userDeviceKeys[event.sender] .deviceKeys[event.content['requesting_device_id']]; if (device.userId == client.userID && device.deviceId == client.deviceID) { - print('[KeyManager] Request is by ourself, ignoring'); + Logs.info('[KeyManager] Request is by ourself, ignoring'); return; // ignore requests by ourself } final room = client.getRoomById(event.content['body']['room_id']); if (room == null) { - print('[KeyManager] Unknown room, ignoring'); + Logs.info('[KeyManager] Unknown room, ignoring'); return; // unknown room } final sessionId = event.content['body']['session_id']; @@ -488,7 +495,7 @@ class KeyManager { // okay, let's see if we have this session at all if ((await loadInboundGroupSession(room.id, sessionId, senderKey)) == null) { - print('[KeyManager] Unknown session, ignoring'); + Logs.info('[KeyManager] Unknown session, ignoring'); return; // we don't have this session anyways } final request = KeyManagerKeyShareRequest( @@ -499,7 +506,7 @@ class KeyManager { senderKey: senderKey, ); 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 } incomingShareRequests[request.requestId] = request; @@ -508,11 +515,12 @@ class KeyManager { if (device.userId == client.userID && device.verified && !device.blocked) { - print('[KeyManager] All checks out, forwarding key...'); + Logs.info('[KeyManager] All checks out, forwarding key...'); // alright, we can forward the key await roomKeyRequest.forwardKey(); } else { - print('[KeyManager] Asking client, if the key should be forwarded'); + Logs.info( + '[KeyManager] Asking client, if the key should be forwarded'); client.onRoomKeyRequest .add(roomKeyRequest); // let the client handle this } diff --git a/lib/encryption/olm_manager.dart b/lib/encryption/olm_manager.dart index 743e432..e068208 100644 --- a/lib/encryption/olm_manager.dart +++ b/lib/encryption/olm_manager.dart @@ -18,6 +18,7 @@ import 'dart:convert'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:pedantic/pedantic.dart'; import 'package:canonical_json/canonical_json.dart'; import 'package:famedlysdk/famedlysdk.dart'; @@ -119,9 +120,9 @@ class OlmManager { try { olmutil.ed25519_verify(key, message, signature); isValid = true; - } catch (e) { + } catch (e, s) { isValid = false; - print('[LibOlm] Signature check failed: ' + e.toString()); + Logs.error('[LibOlm] Signature check failed: ' + e.toString(), s); } finally { olmutil.free(); } @@ -408,10 +409,12 @@ class OlmManager { lastReceived: DateTime.now(), // we want to use a newly created session )); - } catch (e) { + } catch (e, s) { session.free(); - print('[LibOlm] Could not create new outbound olm session: ' + - e.toString()); + Logs.error( + '[LibOlm] Could not create new outbound olm session: ' + + e.toString(), + s); } } } @@ -483,8 +486,9 @@ class OlmManager { try { data[device.userId][device.deviceId] = await encryptToDeviceMessagePayload(device, type, payload); - } catch (e) { - print('[LibOlm] Error encrypting to-device event: ' + e.toString()); + } catch (e, s) { + Logs.error( + '[LibOlm] Error encrypting to-device event: ' + e.toString(), s); continue; } } diff --git a/lib/encryption/ssss.dart b/lib/encryption/ssss.dart index 9349a14..49b35ef 100644 --- a/lib/encryption/ssss.dart +++ b/lib/encryption/ssss.dart @@ -22,6 +22,7 @@ import 'dart:convert'; import 'package:encrypt/encrypt.dart'; import 'package:crypto/crypto.dart'; import 'package:base58check/base58.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:password_hash/password_hash.dart'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; @@ -253,14 +254,14 @@ class SSSS { Future request(String type, List devices) async { // only send to own, verified devices - print('[SSSS] Requesting type ${type}...'); + Logs.info('[SSSS] Requesting type ${type}...'); devices.removeWhere((DeviceKeys d) => d.userId != client.userID || !d.verified || d.blocked || d.deviceId == client.deviceID); if (devices.isEmpty) { - print('[SSSS] Warn: No devices'); + Logs.warning('[SSSS] No devices'); return; } final requestId = client.generateUniqueTransactionId(); @@ -281,31 +282,32 @@ class SSSS { Future handleToDeviceEvent(ToDeviceEvent event) async { if (event.type == 'm.secret.request') { // got a request to share a secret - print('[SSSS] Received sharing request...'); + Logs.info('[SSSS] Received sharing request...'); if (event.sender != 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 } 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 } final device = client.userDeviceKeys[client.userID] .deviceKeys[event.content['requesting_device_id']]; 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 } // alright, all seems fine...let's check if we actually have the secret they are asking for final type = event.content['name']; final secret = await getCached(type); 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 } // 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( [device], 'm.secret.send', @@ -315,11 +317,11 @@ class SSSS { }); } else if (event.type == 'm.secret.send') { // receiving a secret we asked for - print('[SSSS] Received shared secret...'); + Logs.info('[SSSS] Received shared secret...'); if (event.sender != client.userID || !pendingShareRequests.containsKey(event.content['request_id']) || 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 } final request = pendingShareRequests[event.content['request_id']]; @@ -330,26 +332,26 @@ class SSSS { d.curve25519Key == event.encryptedContent['sender_key'], orElse: () => 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 } final secret = event.content['secret']; 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? } // let's validate if the secret is, well, valid if (_validators.containsKey(request.type) && !(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 } pendingShareRequests.remove(request.requestId); 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 } - 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) { final keyId = keyIdFromType(request.type); if (keyId != null) { diff --git a/lib/encryption/utils/key_verification.dart b/lib/encryption/utils/key_verification.dart index fbcab32..8250068 100644 --- a/lib/encryption/utils/key_verification.dart +++ b/lib/encryption/utils/key_verification.dart @@ -19,6 +19,7 @@ import 'dart:async'; import 'dart:typed_data'; import 'package:canonical_json/canonical_json.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:pedantic/pedantic.dart'; import 'package:olm/olm.dart' as olm; import 'package:famedlysdk/famedlysdk.dart'; @@ -150,7 +151,7 @@ class KeyVerification { } void dispose() { - print('[Key Verification] disposing object...'); + Logs.info('[Key Verification] disposing object...'); method?.dispose(); } @@ -202,7 +203,8 @@ class KeyVerification { await Future.delayed(Duration(milliseconds: 50)); } _handlePayloadLock = true; - print('[Key Verification] Received type ${type}: ' + payload.toString()); + Logs.info( + '[Key Verification] Received type ${type}: ' + payload.toString()); try { var thisLastStep = lastStep; switch (type) { @@ -297,7 +299,7 @@ class KeyVerification { startPaylaod = payload; setState(KeyVerificationState.askAccept); } else { - print('handling start in method.....'); + Logs.info('handling start in method.....'); await method.handlePayload(type, payload); } break; @@ -322,8 +324,8 @@ class KeyVerification { lastStep = type; } } catch (err, stacktrace) { - print('[Key Verification] An error occured: ' + err.toString()); - print(stacktrace); + Logs.error( + '[Key Verification] An error occured: ' + err.toString(), stacktrace); await cancel('m.invalid_message'); } finally { _handlePayloadLock = false; @@ -550,9 +552,10 @@ class KeyVerification { Future send(String type, Map payload) async { makePayload(payload); - print('[Key Verification] Sending type ${type}: ' + payload.toString()); + Logs.info('[Key Verification] Sending type ${type}: ' + payload.toString()); 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)) { payload['msgtype'] = type; payload['to'] = userId; @@ -566,7 +569,8 @@ class KeyVerification { encryption.keyVerificationManager.addRequest(this); } } else { - print('[Key Verification] Sending to ${userId} device ${deviceId}...'); + Logs.info( + '[Key Verification] Sending to ${userId} device ${deviceId}...'); await client.sendToDevice( [client.userDeviceKeys[userId].deviceKeys[deviceId]], type, payload); } @@ -693,8 +697,8 @@ class _KeyVerificationMethodSas extends _KeyVerificationMethod { break; } } catch (err, stacktrace) { - print('[Key Verification SAS] An error occured: ' + err.toString()); - print(stacktrace); + Logs.error('[Key Verification SAS] An error occured: ' + err.toString(), + stacktrace); if (request.deviceId != null) { await request.cancel('m.invalid_message'); } diff --git a/lib/encryption/utils/olm_session.dart b/lib/encryption/utils/olm_session.dart index 1dca413..73d8a98 100644 --- a/lib/encryption/utils/olm_session.dart +++ b/lib/encryption/utils/olm_session.dart @@ -16,6 +16,7 @@ * along with this program. If not, see . */ +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:olm/olm.dart' as olm; import '../../src/database/database.dart' show DbOlmSessions; @@ -46,8 +47,8 @@ class OlmSession { lastReceived = dbEntry.lastReceived ?? DateTime.fromMillisecondsSinceEpoch(0); assert(sessionId == session.session_id()); - } catch (e) { - print('[LibOlm] Could not unpickle olm session: ' + e.toString()); + } catch (e, s) { + Logs.error('[LibOlm] Could not unpickle olm session: ' + e.toString(), s); dispose(); } } diff --git a/lib/encryption/utils/outbound_group_session.dart b/lib/encryption/utils/outbound_group_session.dart index 2a1c617..bf10818 100644 --- a/lib/encryption/utils/outbound_group_session.dart +++ b/lib/encryption/utils/outbound_group_session.dart @@ -18,6 +18,7 @@ import 'dart:convert'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:olm/olm.dart' as olm; import '../../src/database/database.dart' show DbOutboundGroupSession; @@ -44,10 +45,11 @@ class OutboundGroupSession { devices = List.from(json.decode(dbEntry.deviceIds)); creationTime = dbEntry.creationTime; sentMessages = dbEntry.sentMessages; - } catch (e) { + } catch (e, s) { dispose(); - print( - '[LibOlm] Unable to unpickle outboundGroupSession: ' + e.toString()); + Logs.error( + '[LibOlm] Unable to unpickle outboundGroupSession: ' + e.toString(), + s); } } diff --git a/lib/encryption/utils/session_key.dart b/lib/encryption/utils/session_key.dart index 5c6f0b2..176c9e0 100644 --- a/lib/encryption/utils/session_key.dart +++ b/lib/encryption/utils/session_key.dart @@ -18,6 +18,7 @@ import 'dart:convert'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:olm/olm.dart' as olm; import 'package:famedlysdk/famedlysdk.dart'; @@ -48,9 +49,11 @@ class SessionKey { inboundGroupSession = olm.InboundGroupSession(); try { inboundGroupSession.unpickle(key, dbEntry.pickle); - } catch (e) { + } catch (e, s) { dispose(); - print('[LibOlm] Unable to unpickle inboundGroupSession: ' + e.toString()); + Logs.error( + '[LibOlm] Unable to unpickle inboundGroupSession: ' + e.toString(), + s); } } diff --git a/lib/src/client.dart b/lib/src/client.dart index 8eb3907..74d75c1 100644 --- a/lib/src/client.dart +++ b/lib/src/client.dart @@ -25,6 +25,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/src/room.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/to_device_event.dart'; import 'package:http/http.dart' as http; @@ -147,7 +148,7 @@ class Client { /// Warning! This endpoint is for testing only! set rooms(List newList) { - print('Warning! This endpoint is for testing only!'); + Logs.warning('Warning! This endpoint is for testing only!'); _rooms = newList; } @@ -368,8 +369,8 @@ class Client { Future logout() async { try { await api.logout(); - } catch (exception) { - print(exception); + } catch (e, s) { + Logs.error(e, s); rethrow; } finally { await clear(); @@ -664,6 +665,9 @@ class Client { } onLoginStateChanged.add(LoginState.logged); + Logs.success( + 'Successfully connected as ${userID.localpart} with ${api.homeserver.toString()}', + ); return _sync(); } @@ -734,8 +738,7 @@ class Client { if (isLogged() == false || _disposed) { return; } - print('Error during processing events: ' + e.toString()); - print(s); + Logs.error('Error during processing events: ' + e.toString(), s); onSyncError.add(SyncError( exception: e is Exception ? e : Exception(e), stackTrace: s)); await Future.delayed(Duration(seconds: syncErrorTimeoutSec), _sync); @@ -814,10 +817,10 @@ class Client { try { toDeviceEvent = await encryption.decryptToDeviceEvent(toDeviceEvent); } catch (e, s) { - print( - '[LibOlm] Could not decrypt to device event from ${toDeviceEvent.sender} with content: ${toDeviceEvent.content}'); - print(e); - print(s); + Logs.error( + '[LibOlm] Could not decrypt to device event from ${toDeviceEvent.sender} with content: ${toDeviceEvent.content}\n${e.toString()}', + s); + onOlmError.add( ToDeviceEventDecryptionError( exception: e is Exception ? e : Exception(e), @@ -1161,8 +1164,8 @@ class Client { userIds.add(user.id); } } - } catch (err) { - print('[E2EE] Failed to fetch participants: ' + err.toString()); + } catch (e, s) { + Logs.error('[E2EE] Failed to fetch participants: ' + e.toString(), s); } } } @@ -1338,8 +1341,9 @@ class Client { } }); } - } catch (e) { - print('[LibOlm] Unable to update user device keys: ' + e.toString()); + } catch (e, s) { + Logs.error( + '[LibOlm] Unable to update user device keys: ' + e.toString(), s); } } diff --git a/lib/src/database/database.dart b/lib/src/database/database.dart index 6caec77..793fd48 100644 --- a/lib/src/database/database.dart +++ b/lib/src/database/database.dart @@ -1,3 +1,4 @@ +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:moor/moor.dart'; import 'dart:convert'; @@ -66,7 +67,7 @@ class Database extends _$Database { if (executor.dialect == SqlDialect.sqlite) { final ret = await customSelect('PRAGMA journal_mode=WAL').get(); if (ret.isNotEmpty) { - print('[Moor] Switched database to mode ' + + Logs.info('[Moor] Switched database to mode ' + ret.first.data['journal_mode'].toString()); } } @@ -113,8 +114,9 @@ class Database extends _$Database { var session = olm.Session(); session.unpickle(userId, row.pickle); res[row.identityKey].add(session); - } catch (e) { - print('[LibOlm] Could not unpickle olm session: ' + e.toString()); + } catch (e, s) { + Logs.error( + '[LibOlm] Could not unpickle olm session: ' + e.toString(), s); } } return res; diff --git a/lib/src/event.dart b/lib/src/event.dart index 6305a1c..df0aa03 100644 --- a/lib/src/event.dart +++ b/lib/src/event.dart @@ -20,6 +20,7 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/encryption.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:famedlysdk/src/utils/receipt.dart'; import 'package:http/http.dart' as http; import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; @@ -96,12 +97,18 @@ class Event extends MatrixEvent { this.senderId = senderId; this.unsigned = unsigned; // synapse unfortunatley isn't following the spec and tosses the prev_content - // into the unsigned block - this.prevContent = prevContent != null && prevContent.isNotEmpty - ? prevContent - : (unsigned != null && unsigned['prev_content'] is Map) - ? unsigned['prev_content'] - : null; + // into the unsigned block. + // Currently we are facing a very strange bug in web which is impossible to debug. + // It may be because of this line so we put this in try-catch until we can fix it. + try { + this.prevContent = (prevContent != null && prevContent.isNotEmpty) + ? 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.originServerTs = originServerTs; } diff --git a/lib/src/room.dart b/lib/src/room.dart index 8ba80b8..b085d50 100644 --- a/lib/src/room.dart +++ b/lib/src/room.dart @@ -23,6 +23,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/src/client.dart'; import 'package:famedlysdk/src/event.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/matrix_file.dart'; import 'package:matrix_file_e2ee/matrix_file_e2ee.dart'; @@ -136,8 +137,8 @@ class Room { if (state.type == EventTypes.Encrypted && client.encryptionEnabled) { try { state = client.encryption.decryptRoomEventSync(id, state); - } catch (e) { - print('[LibOlm] Could not decrypt room state: ' + e.toString()); + } catch (e, s) { + Logs.error('[LibOlm] Could not decrypt room state: ' + e.toString(), s); } } if (!(state.stateKey is String) && @@ -715,8 +716,9 @@ class Room { syncUpdate.rooms.join.values.first.timeline.events.first.eventId = res; await client.handleSync(syncUpdate); return res; - } catch (exception) { - print('[Client] Error while sending: ' + exception.toString()); + } catch (e, s) { + Logs.warning( + '[Client] Problem while sending message: ' + e.toString(), s); syncUpdate.rooms.join.values.first.timeline.events.first .unsigned[MessageSendingStatusKey] = -1; await client.handleSync(syncUpdate); diff --git a/lib/src/timeline.dart b/lib/src/timeline.dart index 042e811..18fe0bf 100644 --- a/lib/src/timeline.dart +++ b/lib/src/timeline.dart @@ -19,6 +19,7 @@ import 'dart:async'; import 'package:famedlysdk/matrix_api.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'event.dart'; import 'room.dart'; @@ -263,8 +264,7 @@ class Timeline { } sortAndUpdate(); } catch (e, s) { - print('[WARNING] (_handleEventUpdate) ${e.toString()}'); - print(s); + Logs.warning('Handle event update failed: ${e.toString()}', s); } } diff --git a/lib/src/utils/event_update.dart b/lib/src/utils/event_update.dart index 0be1c4e..514966b 100644 --- a/lib/src/utils/event_update.dart +++ b/lib/src/utils/event_update.dart @@ -18,6 +18,7 @@ import '../../famedlysdk.dart'; import '../../matrix_api.dart'; +import 'logs.dart'; /// Represents a new event (e.g. a message in a room) or an update for an /// already known event. @@ -57,8 +58,8 @@ class EventUpdate { content: decrpytedEvent.toJson(), sortOrder: sortOrder, ); - } catch (e) { - print('[LibOlm] Could not decrypt megolm event: ' + e.toString()); + } catch (e, s) { + Logs.error('[LibOlm] Could not decrypt megolm event: ' + e.toString(), s); return this; } } diff --git a/lib/src/utils/logs.dart b/lib/src/utils/logs.dart new file mode 100644 index 0000000..f774de3 --- /dev/null +++ b/lib/src/utils/logs.dart @@ -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()}' : ''), + ); +} diff --git a/pubspec.lock b/pubspec.lock index faec33f..25d83fe 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.2" + ansicolor: + dependency: "direct main" + description: + name: ansicolor + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" args: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a82843e..d594d4c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -21,6 +21,7 @@ dependencies: password_hash: ^2.0.0 olm: ^1.2.1 matrix_file_e2ee: ^1.0.4 + ansicolor: ^1.0.2 dev_dependencies: test: ^1.0.0 diff --git a/test/client_test.dart b/test/client_test.dart index c970708..8d0242f 100644 --- a/test/client_test.dart +++ b/test/client_test.dart @@ -23,6 +23,7 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/src/client.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/matrix_file.dart'; import 'package:olm/olm.dart' as olm; @@ -59,9 +60,9 @@ void main() { olm.Account(); } catch (_) { 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 { var presenceCounter = 0; diff --git a/test/device_keys_list_test.dart b/test/device_keys_list_test.dart index a98ff1b..4b870d3 100644 --- a/test/device_keys_list_test.dart +++ b/test/device_keys_list_test.dart @@ -19,6 +19,7 @@ import 'dart:convert'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -74,9 +75,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/cross_signing_test.dart b/test/encryption/cross_signing_test.dart index 4ec212b..fe22982 100644 --- a/test/encryption/cross_signing_test.dart +++ b/test/encryption/cross_signing_test.dart @@ -19,6 +19,7 @@ import 'dart:convert'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -33,9 +34,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/encrypt_decrypt_room_message_test.dart b/test/encryption/encrypt_decrypt_room_message_test.dart index 70d75fa..711a4a4 100644 --- a/test/encryption/encrypt_decrypt_room_message_test.dart +++ b/test/encryption/encrypt_decrypt_room_message_test.dart @@ -17,6 +17,7 @@ */ import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -30,9 +31,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/encrypt_decrypt_to_device_test.dart b/test/encryption/encrypt_decrypt_to_device_test.dart index a56adee..b98ef22 100644 --- a/test/encryption/encrypt_decrypt_to_device_test.dart +++ b/test/encryption/encrypt_decrypt_to_device_test.dart @@ -17,6 +17,7 @@ */ import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -35,9 +36,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/key_manager_test.dart b/test/encryption/key_manager_test.dart index 5b3025f..bdd0304 100644 --- a/test/encryption/key_manager_test.dart +++ b/test/encryption/key_manager_test.dart @@ -17,6 +17,7 @@ */ import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -30,9 +31,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/key_request_test.dart b/test/encryption/key_request_test.dart index c7dbb9f..b780d2b 100644 --- a/test/encryption/key_request_test.dart +++ b/test/encryption/key_request_test.dart @@ -18,6 +18,7 @@ import 'dart:convert'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -45,9 +46,9 @@ void main() { olm.Account(); } catch (_) { 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; @@ -106,7 +107,7 @@ void main() { 'requesting_device_id': 'OTHERDEVICE', }); await matrix.encryption.keyManager.handleToDeviceEvent(event); - print(FakeMatrixApi.calledEndpoints.keys.toString()); + Logs.info(FakeMatrixApi.calledEndpoints.keys.toString()); expect( FakeMatrixApi.calledEndpoints.keys.any( (k) => k.startsWith('/client/r0/sendToDevice/m.room.encrypted')), diff --git a/test/encryption/key_verification_test.dart b/test/encryption/key_verification_test.dart index 3216b8e..5ae9689 100644 --- a/test/encryption/key_verification_test.dart +++ b/test/encryption/key_verification_test.dart @@ -20,6 +20,7 @@ import 'dart:convert'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/encryption.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -67,9 +68,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/olm_manager_test.dart b/test/encryption/olm_manager_test.dart index bf0e7a3..78e7068 100644 --- a/test/encryption/olm_manager_test.dart +++ b/test/encryption/olm_manager_test.dart @@ -18,6 +18,7 @@ import 'dart:convert'; import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -32,9 +33,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/online_key_backup_test.dart b/test/encryption/online_key_backup_test.dart index 0a3b842..12b9ae0 100644 --- a/test/encryption/online_key_backup_test.dart +++ b/test/encryption/online_key_backup_test.dart @@ -17,6 +17,7 @@ */ import 'package:famedlysdk/famedlysdk.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:olm/olm.dart' as olm; @@ -30,9 +31,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test/encryption/ssss_test.dart b/test/encryption/ssss_test.dart index 7c0c641..d213248 100644 --- a/test/encryption/ssss_test.dart +++ b/test/encryption/ssss_test.dart @@ -22,6 +22,7 @@ import 'dart:convert'; import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; import 'package:famedlysdk/encryption.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import 'package:test/test.dart'; import 'package:encrypt/encrypt.dart'; import 'package:olm/olm.dart' as olm; @@ -37,9 +38,9 @@ void main() { olm.Account(); } catch (_) { 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; diff --git a/test_driver/famedlysdk_test.dart b/test_driver/famedlysdk_test.dart index 6b40f53..61f3cdc 100644 --- a/test_driver/famedlysdk_test.dart +++ b/test_driver/famedlysdk_test.dart @@ -1,5 +1,6 @@ import 'package:famedlysdk/famedlysdk.dart'; import 'package:famedlysdk/matrix_api.dart'; +import 'package:famedlysdk/src/utils/logs.dart'; import '../test/fake_database.dart'; void main() => test(); @@ -17,21 +18,21 @@ const String testMessage5 = 'Hello earth'; const String testMessage6 = 'Hello mars'; void test() async { - print('++++ Login $testUserA ++++'); + Logs.success('++++ Login $testUserA ++++'); var testClientA = Client('TestClientA'); testClientA.database = getDatabase(); await testClientA.checkServer(homeserver); await testClientA.login(testUserA, testPasswordA); assert(testClientA.encryptionEnabled); - print('++++ Login $testUserB ++++'); + Logs.success('++++ Login $testUserB ++++'); var testClientB = Client('TestClientB'); testClientB.database = getDatabase(); await testClientB.checkServer(homeserver); await testClientB.login(testUserB, testPasswordA); assert(testClientB.encryptionEnabled); - print('++++ ($testUserA) Leave all rooms ++++'); + Logs.success('++++ ($testUserA) Leave all rooms ++++'); while (testClientA.rooms.isNotEmpty) { var room = testClientA.rooms.first; if (room.canonicalAlias?.isNotEmpty ?? false) { @@ -43,7 +44,7 @@ void test() async { } catch (_) {} } - print('++++ ($testUserB) Leave all rooms ++++'); + Logs.success('++++ ($testUserB) Leave all rooms ++++'); for (var i = 0; i < 3; i++) { if (testClientB.rooms.isNotEmpty) { 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[testUserA].deviceKeys .containsKey(testClientA.deviceID)); @@ -70,20 +71,20 @@ void test() async { assert(!testClientB .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 Future.delayed(Duration(seconds: 1)); var room = testClientA.rooms.first; assert(room != null); final roomId = room.id; - print('++++ ($testUserB) Join room ++++'); + Logs.success('++++ ($testUserB) Join room ++++'); var inviteRoom = testClientB.getRoomById(roomId); await inviteRoom.join(); await Future.delayed(Duration(seconds: 1)); assert(inviteRoom.membership == Membership.join); - print('++++ ($testUserA) Enable encryption ++++'); + Logs.success('++++ ($testUserA) Enable encryption ++++'); assert(room.encrypted == false); await room.enableEncryption(); await Future.delayed(Duration(seconds: 5)); @@ -91,7 +92,7 @@ void test() async { assert(room.client.encryption.keyManager.getOutboundGroupSession(room.id) == null); - print('++++ ($testUserA) Check known olm devices ++++'); + Logs.success('++++ ($testUserA) Check known olm devices ++++'); assert(testClientA.userDeviceKeys.containsKey(testUserB)); assert(testClientA.userDeviceKeys[testUserB].deviceKeys .containsKey(testClientB.deviceID)); @@ -109,7 +110,7 @@ void test() async { await testClientA.userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID] .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[testUserA].deviceKeys .containsKey(testClientA.deviceID)); @@ -121,7 +122,7 @@ void test() async { assert(testClientB .userDeviceKeys[testUserB].deviceKeys[testClientB.deviceID].verified); - print("++++ ($testUserA) Send encrypted message: '$testMessage' ++++"); + Logs.success("++++ ($testUserA) Send encrypted message: '$testMessage' ++++"); await room.sendTextEvent(testMessage); await Future.delayed(Duration(seconds: 5)); assert(room.client.encryption.keyManager.getOutboundGroupSession(room.id) != @@ -148,10 +149,11 @@ void test() async { null); assert(room.lastMessage == testMessage); assert(inviteRoom.lastMessage == testMessage); - print( + Logs.success( "++++ ($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 Future.delayed(Duration(seconds: 5)); assert(testClientA @@ -175,10 +177,11 @@ void test() async { null); assert(room.lastMessage == testMessage2); assert(inviteRoom.lastMessage == testMessage2); - print( + Logs.success( "++++ ($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 Future.delayed(Duration(seconds: 5)); assert(testClientA @@ -208,16 +211,17 @@ void test() async { null); assert(inviteRoom.lastMessage == testMessage3); assert(room.lastMessage == testMessage3); - print( + Logs.success( "++++ ($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()); await testClientC.checkServer(homeserver); await testClientC.login(testUserB, testPasswordA); 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 Future.delayed(Duration(seconds: 5)); assert(testClientA @@ -254,16 +258,17 @@ void test() async { null); assert(room.lastMessage == testMessage4); assert(inviteRoom.lastMessage == testMessage4); - print( + Logs.success( "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); - print('++++ Logout $testUserB another client ++++'); + Logs.success('++++ Logout $testUserB another client ++++'); await testClientC.dispose(); await testClientC.logout(); testClientC = null; 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 Future.delayed(Duration(seconds: 5)); assert(testClientA @@ -290,10 +295,10 @@ void test() async { null); assert(room.lastMessage == testMessage6); assert(inviteRoom.lastMessage == testMessage6); - print( + Logs.success( "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++"); -/* print('++++ ($testUserA) Restore user ++++'); +/* Logs.success('++++ ($testUserA) Restore user ++++'); await testClientA.dispose(); testClientA = null; testClientA = Client( @@ -320,7 +325,7 @@ void test() async { assert(testClientA.encryption.olmManager.olmSessions[testClientB.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 Future.delayed(Duration(seconds: 5)); assert(testClientA.encryption.olmManager.olmSessions[testClientB.identityKey].length == 1); @@ -330,10 +335,10 @@ void test() async { assert(restoredRoom.lastMessage == testMessage5); assert(inviteRoom.lastMessage == testMessage5); assert(testClientB.getRoomById(roomId).lastMessage == testMessage5); - print( + Logs.success( "++++ ($testUserB) Received decrypted message: '${inviteRoom.lastMessage}' ++++");*/ - print('++++ Logout $testUserA and $testUserB ++++'); + Logs.success('++++ Logout $testUserA and $testUserB ++++'); await room.leave(); await room.forget(); await inviteRoom.leave();