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:
rules:
- camel_case_types
- avoid_print
analyzer:
errors:
todo: ignore
exclude:
- example/main.dart
- lib/src/utils/logs.dart

View file

@ -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 = <String, dynamic>{
@ -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
}

View file

@ -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;
}
}

View file

@ -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<void> request(String type, List<DeviceKeys> 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<void> 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) {

View file

@ -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<void> send(String type, Map<String, dynamic> 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');
}

View file

@ -16,6 +16,7 @@
* 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 '../../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();
}
}

View file

@ -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<String>.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);
}
}

View file

@ -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);
}
}

View file

@ -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<Room> 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<void> 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);
}
}

View file

@ -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;

View file

@ -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
// 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;
}

View file

@ -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);

View file

@ -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);
}
}

View file

@ -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;
}
}

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"
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:

View file

@ -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

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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')),

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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();