feat: Add fallback keys support
This commit is contained in:
parent
82f823f50e
commit
498c7825a5
|
|
@ -20,6 +20,7 @@ import 'dart:convert';
|
||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:pedantic/pedantic.dart';
|
import 'package:pedantic/pedantic.dart';
|
||||||
|
import 'package:olm/olm.dart' as olm;
|
||||||
|
|
||||||
import '../famedlysdk.dart';
|
import '../famedlysdk.dart';
|
||||||
import '../src/utils/run_in_root.dart';
|
import '../src/utils/run_in_root.dart';
|
||||||
|
|
@ -68,13 +69,27 @@ class Encryption {
|
||||||
_backgroundTasks(); // start the background tasks
|
_backgroundTasks(); // start the background tasks
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool isMinOlmVersion(int major, int minor, int patch) {
|
||||||
|
try {
|
||||||
|
final version = olm.get_library_version();
|
||||||
|
return version[0] > major ||
|
||||||
|
(version[0] == major &&
|
||||||
|
(version[1] > minor ||
|
||||||
|
(version[1] == minor && version[2] >= patch)));
|
||||||
|
} catch (_) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Bootstrap bootstrap({void Function() onUpdate}) => Bootstrap(
|
Bootstrap bootstrap({void Function() onUpdate}) => Bootstrap(
|
||||||
encryption: this,
|
encryption: this,
|
||||||
onUpdate: onUpdate,
|
onUpdate: onUpdate,
|
||||||
);
|
);
|
||||||
|
|
||||||
void handleDeviceOneTimeKeysCount(Map<String, int> countJson) {
|
void handleDeviceOneTimeKeysCount(
|
||||||
runInRoot(() => olmManager.handleDeviceOneTimeKeysCount(countJson));
|
Map<String, int> countJson, List<String> unusedFallbackKeyTypes) {
|
||||||
|
runInRoot(() => olmManager.handleDeviceOneTimeKeysCount(
|
||||||
|
countJson, unusedFallbackKeyTypes));
|
||||||
}
|
}
|
||||||
|
|
||||||
void onSync() {
|
void onSync() {
|
||||||
|
|
|
||||||
|
|
@ -138,10 +138,12 @@ class OlmManager {
|
||||||
bool _uploadKeysLock = false;
|
bool _uploadKeysLock = false;
|
||||||
|
|
||||||
/// Generates new one time keys, signs everything and upload it to the server.
|
/// Generates new one time keys, signs everything and upload it to the server.
|
||||||
Future<bool> uploadKeys(
|
Future<bool> uploadKeys({
|
||||||
{bool uploadDeviceKeys = false,
|
bool uploadDeviceKeys = false,
|
||||||
int oldKeyCount = 0,
|
int oldKeyCount = 0,
|
||||||
bool updateDatabase = true}) async {
|
bool updateDatabase = true,
|
||||||
|
bool unusedFallbackKey = false,
|
||||||
|
}) async {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -152,32 +154,53 @@ class OlmManager {
|
||||||
_uploadKeysLock = true;
|
_uploadKeysLock = true;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// check if we have OTKs that still need uploading. If we do, we don't try to generate new ones,
|
|
||||||
// instead we try to upload the old ones first
|
|
||||||
final oldOTKsNeedingUpload =
|
|
||||||
json.decode(_olmAccount.one_time_keys())['curve25519'].entries.length;
|
|
||||||
// generate one-time keys
|
|
||||||
// we generate 2/3rds of max, so that other keys people may still have can
|
|
||||||
// still be used
|
|
||||||
final oneTimeKeysCount =
|
|
||||||
(_olmAccount.max_number_of_one_time_keys() * 2 / 3).floor() -
|
|
||||||
oldKeyCount -
|
|
||||||
oldOTKsNeedingUpload;
|
|
||||||
if (oneTimeKeysCount > 0) {
|
|
||||||
_olmAccount.generate_one_time_keys(oneTimeKeysCount);
|
|
||||||
}
|
|
||||||
final Map<String, dynamic> oneTimeKeys =
|
|
||||||
json.decode(_olmAccount.one_time_keys());
|
|
||||||
|
|
||||||
// now sign all the one-time keys
|
|
||||||
final signedOneTimeKeys = <String, dynamic>{};
|
final signedOneTimeKeys = <String, dynamic>{};
|
||||||
for (final entry in oneTimeKeys['curve25519'].entries) {
|
int uploadedOneTimeKeysCount;
|
||||||
final key = entry.key;
|
if (oldKeyCount != null) {
|
||||||
final value = entry.value;
|
// check if we have OTKs that still need uploading. If we do, we don't try to generate new ones,
|
||||||
signedOneTimeKeys['signed_curve25519:$key'] = <String, dynamic>{};
|
// instead we try to upload the old ones first
|
||||||
signedOneTimeKeys['signed_curve25519:$key'] = signJson({
|
final oldOTKsNeedingUpload = json
|
||||||
'key': value,
|
.decode(_olmAccount.one_time_keys())['curve25519']
|
||||||
});
|
.entries
|
||||||
|
.length;
|
||||||
|
// generate one-time keys
|
||||||
|
// we generate 2/3rds of max, so that other keys people may still have can
|
||||||
|
// still be used
|
||||||
|
final oneTimeKeysCount =
|
||||||
|
(_olmAccount.max_number_of_one_time_keys() * 2 / 3).floor() -
|
||||||
|
oldKeyCount -
|
||||||
|
oldOTKsNeedingUpload;
|
||||||
|
if (oneTimeKeysCount > 0) {
|
||||||
|
_olmAccount.generate_one_time_keys(oneTimeKeysCount);
|
||||||
|
}
|
||||||
|
uploadedOneTimeKeysCount = oneTimeKeysCount + oldOTKsNeedingUpload;
|
||||||
|
final Map<String, dynamic> oneTimeKeys =
|
||||||
|
json.decode(_olmAccount.one_time_keys());
|
||||||
|
|
||||||
|
// now sign all the one-time keys
|
||||||
|
for (final entry in oneTimeKeys['curve25519'].entries) {
|
||||||
|
final key = entry.key;
|
||||||
|
final value = entry.value;
|
||||||
|
signedOneTimeKeys['signed_curve25519:$key'] = signJson({
|
||||||
|
'key': value,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
final signedFallbackKeys = <String, dynamic>{};
|
||||||
|
if (encryption.isMinOlmVersion(3, 2, 0) && unusedFallbackKey == false) {
|
||||||
|
// we don't have an unused fallback key uploaded....so let's change that!
|
||||||
|
_olmAccount.generate_fallback_key();
|
||||||
|
final fallbackKey = json.decode(_olmAccount.fallback_key());
|
||||||
|
// now sign all the fallback keys
|
||||||
|
for (final entry in fallbackKey['curve25519'].entries) {
|
||||||
|
final key = entry.key;
|
||||||
|
final value = entry.value;
|
||||||
|
signedFallbackKeys['signed_curve25519:$key'] = signJson({
|
||||||
|
'key': value,
|
||||||
|
'fallback': true,
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// and now generate the payload to upload
|
// and now generate the payload to upload
|
||||||
|
|
@ -217,28 +240,43 @@ class OlmManager {
|
||||||
? MatrixDeviceKeys.fromJson(keysContent['device_keys'])
|
? MatrixDeviceKeys.fromJson(keysContent['device_keys'])
|
||||||
: null,
|
: null,
|
||||||
oneTimeKeys: signedOneTimeKeys,
|
oneTimeKeys: signedOneTimeKeys,
|
||||||
|
fallbackKeys: signedFallbackKeys,
|
||||||
);
|
);
|
||||||
// mark the OTKs as published and save that to datbase
|
// mark the OTKs as published and save that to datbase
|
||||||
_olmAccount.mark_keys_as_published();
|
_olmAccount.mark_keys_as_published();
|
||||||
if (updateDatabase) {
|
if (updateDatabase) {
|
||||||
await client.database?.updateClientKeys(pickledOlmAccount, client.id);
|
await client.database?.updateClientKeys(pickledOlmAccount, client.id);
|
||||||
}
|
}
|
||||||
return response['signed_curve25519'] == oneTimeKeysCount;
|
return (uploadedOneTimeKeysCount != null &&
|
||||||
|
response['signed_curve25519'] == uploadedOneTimeKeysCount) ||
|
||||||
|
uploadedOneTimeKeysCount == null;
|
||||||
} finally {
|
} finally {
|
||||||
_uploadKeysLock = false;
|
_uploadKeysLock = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void handleDeviceOneTimeKeysCount(Map<String, int> countJson) {
|
void handleDeviceOneTimeKeysCount(
|
||||||
|
Map<String, int> countJson, List<String> unusedFallbackKeyTypes) {
|
||||||
if (!enabled) {
|
if (!enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
final haveFallbackKeys = encryption.isMinOlmVersion(3, 2, 0);
|
||||||
// Check if there are at least half of max_number_of_one_time_keys left on the server
|
// Check if there are at least half of max_number_of_one_time_keys left on the server
|
||||||
// and generate and upload more if not.
|
// and generate and upload more if not.
|
||||||
if (countJson.containsKey('signed_curve25519') &&
|
if ((countJson != null &&
|
||||||
countJson['signed_curve25519'] <
|
((countJson.containsKey('signed_curve25519') &&
|
||||||
(_olmAccount.max_number_of_one_time_keys() / 2)) {
|
countJson['signed_curve25519'] <
|
||||||
uploadKeys(oldKeyCount: countJson['signed_curve25519']);
|
(_olmAccount.max_number_of_one_time_keys() / 2)) ||
|
||||||
|
!countJson.containsKey('signed_curve25519'))) ||
|
||||||
|
(haveFallbackKeys &&
|
||||||
|
unusedFallbackKeyTypes?.contains('signed_curve25519') == false)) {
|
||||||
|
uploadKeys(
|
||||||
|
oldKeyCount:
|
||||||
|
countJson != null ? (countJson['signed_curve25519'] ?? 0) : null,
|
||||||
|
unusedFallbackKey: haveFallbackKeys
|
||||||
|
? unusedFallbackKeyTypes?.contains('signed_curve25519')
|
||||||
|
: null,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1073,8 +1073,11 @@ class Client extends MatrixApi {
|
||||||
if (sync.deviceLists != null) {
|
if (sync.deviceLists != null) {
|
||||||
await _handleDeviceListsEvents(sync.deviceLists);
|
await _handleDeviceListsEvents(sync.deviceLists);
|
||||||
}
|
}
|
||||||
if (sync.deviceOneTimeKeysCount != null && encryptionEnabled) {
|
if ((sync.deviceUnusedFallbackKeyTypes != null ||
|
||||||
encryption.handleDeviceOneTimeKeysCount(sync.deviceOneTimeKeysCount);
|
sync.deviceOneTimeKeysCount != null) &&
|
||||||
|
encryptionEnabled) {
|
||||||
|
encryption.handleDeviceOneTimeKeysCount(
|
||||||
|
sync.deviceOneTimeKeysCount, sync.deviceUnusedFallbackKeyTypes);
|
||||||
}
|
}
|
||||||
onSync.add(sync);
|
onSync.add(sync);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,11 @@ dependencies:
|
||||||
crypto: ^2.1.5
|
crypto: ^2.1.5
|
||||||
base58check: ^1.0.1
|
base58check: ^1.0.1
|
||||||
password_hash: ^2.0.0
|
password_hash: ^2.0.0
|
||||||
olm: ^1.2.1
|
olm: ^1.3.0
|
||||||
matrix_file_e2ee: ^1.0.5
|
matrix_file_e2ee: ^1.0.5
|
||||||
isolate: ^2.0.3
|
isolate: ^2.0.3
|
||||||
logger: ^0.9.4
|
logger: ^0.9.4
|
||||||
matrix_api_lite: ^0.1.8
|
matrix_api_lite: ^0.1.9
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
test: ^1.15.7
|
test: ^1.15.7
|
||||||
|
|
|
||||||
|
|
@ -61,16 +61,17 @@ void main() {
|
||||||
toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList();
|
toDeviceUpdateListFuture = matrix.onToDeviceEvent.stream.toList();
|
||||||
|
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().w('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
test('Login', () async {
|
test('Login', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().w('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
|
||||||
var presenceCounter = 0;
|
var presenceCounter = 0;
|
||||||
var accountDataCounter = 0;
|
var accountDataCounter = 0;
|
||||||
matrix.onPresence.stream.listen((Presence data) {
|
matrix.onPresence.stream.listen((Presence data) {
|
||||||
|
|
|
||||||
|
|
@ -74,24 +74,25 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reject devices without self-signature', () async {
|
test('reject devices without self-signature', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
var key = DeviceKeys.fromJson({
|
var key = DeviceKeys.fromJson({
|
||||||
'user_id': '@test:fakeServer.notExisting',
|
'user_id': '@test:fakeServer.notExisting',
|
||||||
'device_id': 'BADDEVICE',
|
'device_id': 'BADDEVICE',
|
||||||
|
|
@ -128,6 +129,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('set blocked / verified', () async {
|
test('set blocked / verified', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['UNSIGNEDDEVICE'] =
|
client.userDeviceKeys[client.userID].deviceKeys['UNSIGNEDDEVICE'] =
|
||||||
|
|
@ -203,6 +205,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('verification based on signatures', () async {
|
test('verification based on signatures', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final user = client.userDeviceKeys[client.userID];
|
final user = client.userDeviceKeys[client.userID];
|
||||||
user.masterKey.setDirectVerified(true);
|
user.masterKey.setDirectVerified(true);
|
||||||
expect(user.deviceKeys['GHTYAJCE'].crossVerified, true);
|
expect(user.deviceKeys['GHTYAJCE'].crossVerified, true);
|
||||||
|
|
@ -238,6 +241,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('start verification', () async {
|
test('start verification', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
var req = client
|
var req = client
|
||||||
.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
.userDeviceKeys['@alice:example.com'].deviceKeys['JLAFKJWSCS']
|
||||||
.startVerification();
|
.startVerification();
|
||||||
|
|
@ -251,6 +255,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -31,16 +31,6 @@ void main() {
|
||||||
group('Bootstrap', () {
|
group('Bootstrap', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
Map<String, dynamic> oldSecret;
|
Map<String, dynamic> oldSecret;
|
||||||
|
|
@ -52,6 +42,16 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('setup', () async {
|
test('setup', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
Bootstrap bootstrap;
|
Bootstrap bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption.bootstrap(
|
||||||
onUpdate: () async {
|
onUpdate: () async {
|
||||||
|
|
@ -108,6 +108,7 @@ void main() {
|
||||||
}, timeout: Timeout(Duration(minutes: 2)));
|
}, timeout: Timeout(Duration(minutes: 2)));
|
||||||
|
|
||||||
test('change recovery passphrase', () async {
|
test('change recovery passphrase', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
Bootstrap bootstrap;
|
Bootstrap bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption.bootstrap(
|
||||||
onUpdate: () async {
|
onUpdate: () async {
|
||||||
|
|
@ -158,6 +159,7 @@ void main() {
|
||||||
}, timeout: Timeout(Duration(minutes: 2)));
|
}, timeout: Timeout(Duration(minutes: 2)));
|
||||||
|
|
||||||
test('change passphrase with multiple keys', () async {
|
test('change passphrase with multiple keys', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.setAccountData(client.userID, 'foxes', oldSecret);
|
await client.setAccountData(client.userID, 'foxes', oldSecret);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
|
|
||||||
|
|
@ -212,6 +214,7 @@ void main() {
|
||||||
}, timeout: Timeout(Duration(minutes: 2)));
|
}, timeout: Timeout(Duration(minutes: 2)));
|
||||||
|
|
||||||
test('setup new ssss', () async {
|
test('setup new ssss', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client.accountData.clear();
|
client.accountData.clear();
|
||||||
Bootstrap bootstrap;
|
Bootstrap bootstrap;
|
||||||
bootstrap = client.encryption.bootstrap(
|
bootstrap = client.encryption.bootstrap(
|
||||||
|
|
@ -237,6 +240,7 @@ void main() {
|
||||||
}, timeout: Timeout(Duration(minutes: 2)));
|
}, timeout: Timeout(Duration(minutes: 2)));
|
||||||
|
|
||||||
test('bad ssss', () async {
|
test('bad ssss', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client.accountData.clear();
|
client.accountData.clear();
|
||||||
await client.setAccountData(client.userID, 'foxes', oldSecret);
|
await client.setAccountData(client.userID, 'foxes', oldSecret);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
|
|
@ -262,6 +266,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,28 +30,30 @@ void main() {
|
||||||
group('Cross Signing', () {
|
group('Cross Signing', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('basic things', () async {
|
test('basic things', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
expect(client.encryption.crossSigning.enabled, true);
|
expect(client.encryption.crossSigning.enabled, true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('selfSign', () async {
|
test('selfSign', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final key = client.userDeviceKeys[client.userID].masterKey;
|
final key = client.userDeviceKeys[client.userID].masterKey;
|
||||||
key.setDirectVerified(false);
|
key.setDirectVerified(false);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
|
@ -65,6 +67,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('signable', () async {
|
test('signable', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
expect(
|
expect(
|
||||||
client.encryption.crossSigning
|
client.encryption.crossSigning
|
||||||
.signable([client.userDeviceKeys[client.userID].masterKey]),
|
.signable([client.userDeviceKeys[client.userID].masterKey]),
|
||||||
|
|
@ -86,6 +89,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('sign', () async {
|
test('sign', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.crossSigning.sign([
|
await client.encryption.crossSigning.sign([
|
||||||
client.userDeviceKeys[client.userID].masterKey,
|
client.userDeviceKeys[client.userID].masterKey,
|
||||||
|
|
@ -109,6 +113,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -27,16 +27,6 @@ void main() {
|
||||||
group('Encrypt/Decrypt room message', () {
|
group('Encrypt/Decrypt room message', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
final roomId = '!726s6s6q:example.com';
|
final roomId = '!726s6s6q:example.com';
|
||||||
|
|
@ -45,11 +35,22 @@ void main() {
|
||||||
final now = DateTime.now();
|
final now = DateTime.now();
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
room = client.getRoomById(roomId);
|
room = client.getRoomById(roomId);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('encrypt payload', () async {
|
test('encrypt payload', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
payload = await client.encryption.encryptGroupMessagePayload(roomId, {
|
payload = await client.encryption.encryptGroupMessagePayload(roomId, {
|
||||||
'msgtype': 'm.text',
|
'msgtype': 'm.text',
|
||||||
'text': 'Hello foxies!',
|
'text': 'Hello foxies!',
|
||||||
|
|
@ -62,6 +63,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('decrypt payload', () async {
|
test('decrypt payload', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final encryptedEvent = Event(
|
final encryptedEvent = Event(
|
||||||
type: EventTypes.Encrypted,
|
type: EventTypes.Encrypted,
|
||||||
content: payload,
|
content: payload,
|
||||||
|
|
@ -78,6 +80,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('decrypt payload nocache', () async {
|
test('decrypt payload nocache', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption.keyManager.clearInboundGroupSessions();
|
||||||
final encryptedEvent = Event(
|
final encryptedEvent = Event(
|
||||||
type: EventTypes.Encrypted,
|
type: EventTypes.Encrypted,
|
||||||
|
|
@ -98,6 +101,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -33,16 +33,6 @@ void main() {
|
||||||
group('Encrypt/Decrypt to-device messages', () {
|
group('Encrypt/Decrypt to-device messages', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
var otherClient = Client('othertestclient',
|
var otherClient = Client('othertestclient',
|
||||||
|
|
@ -51,6 +41,16 @@ void main() {
|
||||||
Map<String, dynamic> payload;
|
Map<String, dynamic> payload;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
await client.abortSync();
|
await client.abortSync();
|
||||||
await otherClient.checkHomeserver('https://fakeserver.notexisting',
|
await otherClient.checkHomeserver('https://fakeserver.notexisting',
|
||||||
|
|
@ -81,11 +81,13 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('encryptToDeviceMessage', () async {
|
test('encryptToDeviceMessage', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
payload = await otherClient.encryption
|
payload = await otherClient.encryption
|
||||||
.encryptToDeviceMessage([device], 'm.to_device', {'hello': 'foxies'});
|
.encryptToDeviceMessage([device], 'm.to_device', {'hello': 'foxies'});
|
||||||
});
|
});
|
||||||
|
|
||||||
test('decryptToDeviceEvent', () async {
|
test('decryptToDeviceEvent', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final encryptedEvent = ToDeviceEvent(
|
final encryptedEvent = ToDeviceEvent(
|
||||||
sender: '@othertest:fakeServer.notExisting',
|
sender: '@othertest:fakeServer.notExisting',
|
||||||
type: EventTypes.Encrypted,
|
type: EventTypes.Encrypted,
|
||||||
|
|
@ -98,6 +100,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('decryptToDeviceEvent nocache', () async {
|
test('decryptToDeviceEvent nocache', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption.olmManager.olmSessions.clear();
|
||||||
payload = await otherClient.encryption.encryptToDeviceMessage(
|
payload = await otherClient.encryption.encryptToDeviceMessage(
|
||||||
[device], 'm.to_device', {'hello': 'superfoxies'});
|
[device], 'm.to_device', {'hello': 'superfoxies'});
|
||||||
|
|
@ -113,6 +116,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
await otherClient.dispose(closeDatabase: true);
|
await otherClient.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -29,24 +29,25 @@ void main() {
|
||||||
group('Key Manager', () {
|
group('Key Manager', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handle new m.room_key', () async {
|
test('handle new m.room_key', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
||||||
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
||||||
final sessionKey =
|
final sessionKey =
|
||||||
|
|
@ -94,6 +95,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('outbound group session', () async {
|
test('outbound group session', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final roomId = '!726s6s6q:example.com';
|
final roomId = '!726s6s6q:example.com';
|
||||||
expect(
|
expect(
|
||||||
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
client.encryption.keyManager.getOutboundGroupSession(roomId) != null,
|
||||||
|
|
@ -244,6 +246,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('inbound group session', () async {
|
test('inbound group session', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final roomId = '!726s6s6q:example.com';
|
final roomId = '!726s6s6q:example.com';
|
||||||
final sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
final sessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
||||||
final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
||||||
|
|
@ -325,6 +328,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('setInboundGroupSession', () async {
|
test('setInboundGroupSession', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final session = olm.OutboundGroupSession();
|
final session = olm.OutboundGroupSession();
|
||||||
session.create();
|
session.create();
|
||||||
final inbound = olm.InboundGroupSession();
|
final inbound = olm.InboundGroupSession();
|
||||||
|
|
@ -495,6 +499,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -42,20 +42,20 @@ void main() {
|
||||||
group('Key Request', () {
|
group('Key Request', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
final validSessionId = 'ciM/JWTPrmiWPPZNkRLDPQYf9AW/I46bxyLSr+Bx5oU';
|
||||||
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
final validSenderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
||||||
test('Create Request', () async {
|
test('Create Request', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
var matrix = await getClient();
|
var matrix = await getClient();
|
||||||
final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
|
final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
|
||||||
await matrix.encryption.keyManager.request(
|
await matrix.encryption.keyManager.request(
|
||||||
|
|
@ -83,6 +83,7 @@ void main() {
|
||||||
await matrix.dispose(closeDatabase: true);
|
await matrix.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
test('Reply To Request', () async {
|
test('Reply To Request', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
var matrix = await getClient();
|
var matrix = await getClient();
|
||||||
matrix.setUserId('@alice:example.com'); // we need to pretend to be alice
|
matrix.setUserId('@alice:example.com'); // we need to pretend to be alice
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
|
@ -277,6 +278,7 @@ void main() {
|
||||||
await matrix.dispose(closeDatabase: true);
|
await matrix.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
test('Receive shared keys', () async {
|
test('Receive shared keys', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
var matrix = await getClient();
|
var matrix = await getClient();
|
||||||
final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
|
final requestRoom = matrix.getRoomById('!726s6s6q:example.com');
|
||||||
await matrix.encryption.keyManager.request(
|
await matrix.encryption.keyManager.request(
|
||||||
|
|
|
||||||
|
|
@ -64,16 +64,6 @@ void main() {
|
||||||
group('Key Verification', () {
|
group('Key Verification', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
// key @othertest:fakeServer.notExisting
|
// key @othertest:fakeServer.notExisting
|
||||||
const otherPickledOlmAccount =
|
const otherPickledOlmAccount =
|
||||||
|
|
@ -83,6 +73,16 @@ void main() {
|
||||||
Client client2;
|
Client client2;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client1 = await getClient();
|
client1 = await getClient();
|
||||||
client2 = Client('othertestclient',
|
client2 = Client('othertestclient',
|
||||||
httpClient: FakeMatrixApi(),
|
httpClient: FakeMatrixApi(),
|
||||||
|
|
@ -109,6 +109,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Run emoji / number verification', () async {
|
test('Run emoji / number verification', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
// for a full run we test in-room verification in a cleartext room
|
// for a full run we test in-room verification in a cleartext room
|
||||||
// because then we can easily intercept the payloads and inject in the other client
|
// because then we can easily intercept the payloads and inject in the other client
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
|
@ -209,6 +210,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ask SSSS start', () async {
|
test('ask SSSS start', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true);
|
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(true);
|
||||||
await client1.encryption.ssss.clearCache();
|
await client1.encryption.ssss.clearCache();
|
||||||
final req1 =
|
final req1 =
|
||||||
|
|
@ -223,6 +225,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('ask SSSS end', () async {
|
test('ask SSSS end', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
||||||
|
|
@ -327,6 +330,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reject verification', () async {
|
test('reject verification', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
||||||
|
|
@ -355,6 +359,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('reject sas', () async {
|
test('reject sas', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
||||||
|
|
@ -415,6 +420,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('other device accepted', () async {
|
test('other device accepted', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
// make sure our master key is *not* verified to not triger SSSS for now
|
// make sure our master key is *not* verified to not triger SSSS for now
|
||||||
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
client1.userDeviceKeys[client1.userID].masterKey.setDirectVerified(false);
|
||||||
|
|
@ -460,6 +466,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client1.dispose(closeDatabase: true);
|
await client1.dispose(closeDatabase: true);
|
||||||
await client2.dispose(closeDatabase: true);
|
await client2.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,24 +30,25 @@ void main() {
|
||||||
group('Olm Manager', () {
|
group('Olm Manager', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('signatures', () async {
|
test('signatures', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final payload = <String, dynamic>{
|
final payload = <String, dynamic>{
|
||||||
'fox': 'floof',
|
'fox': 'floof',
|
||||||
};
|
};
|
||||||
|
|
@ -59,6 +60,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('uploadKeys', () async {
|
test('uploadKeys', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
final res =
|
final res =
|
||||||
await client.encryption.olmManager.uploadKeys(uploadDeviceKeys: true);
|
await client.encryption.olmManager.uploadKeys(uploadDeviceKeys: true);
|
||||||
|
|
@ -68,22 +70,28 @@ void main() {
|
||||||
expect(sent['device_keys'] != null, true);
|
expect(sent['device_keys'] != null, true);
|
||||||
expect(sent['one_time_keys'] != null, true);
|
expect(sent['one_time_keys'] != null, true);
|
||||||
expect(sent['one_time_keys'].keys.length, 66);
|
expect(sent['one_time_keys'].keys.length, 66);
|
||||||
|
expect(sent['fallback_keys'] != null, true);
|
||||||
|
expect(sent['fallback_keys'].keys.length, 1);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.olmManager.uploadKeys();
|
await client.encryption.olmManager.uploadKeys();
|
||||||
sent = json.decode(
|
sent = json.decode(
|
||||||
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
|
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
|
||||||
expect(sent['device_keys'] != null, false);
|
expect(sent['device_keys'] != null, false);
|
||||||
|
expect(sent['fallback_keys'].keys.length, 1);
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
await client.encryption.olmManager.uploadKeys(oldKeyCount: 20);
|
await client.encryption.olmManager
|
||||||
|
.uploadKeys(oldKeyCount: 20, unusedFallbackKey: true);
|
||||||
sent = json.decode(
|
sent = json.decode(
|
||||||
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
|
FakeMatrixApi.calledEndpoints['/client/r0/keys/upload'].first);
|
||||||
expect(sent['one_time_keys'].keys.length, 46);
|
expect(sent['one_time_keys'].keys.length, 46);
|
||||||
|
expect(sent['fallback_keys'].keys.length, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('handleDeviceOneTimeKeysCount', () async {
|
test('handleDeviceOneTimeKeysCount', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
client.encryption.olmManager
|
client.encryption.olmManager
|
||||||
.handleDeviceOneTimeKeysCount({'signed_curve25519': 20});
|
.handleDeviceOneTimeKeysCount({'signed_curve25519': 20}, null);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
||||||
|
|
@ -91,7 +99,22 @@ void main() {
|
||||||
|
|
||||||
FakeMatrixApi.calledEndpoints.clear();
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
client.encryption.olmManager
|
client.encryption.olmManager
|
||||||
.handleDeviceOneTimeKeysCount({'signed_curve25519': 70});
|
.handleDeviceOneTimeKeysCount({'signed_curve25519': 70}, null);
|
||||||
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
|
expect(
|
||||||
|
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
||||||
|
false);
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
client.encryption.olmManager.handleDeviceOneTimeKeysCount(null, []);
|
||||||
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
|
expect(
|
||||||
|
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
||||||
|
true);
|
||||||
|
|
||||||
|
FakeMatrixApi.calledEndpoints.clear();
|
||||||
|
client.encryption.olmManager
|
||||||
|
.handleDeviceOneTimeKeysCount(null, ['signed_curve25519']);
|
||||||
await Future.delayed(Duration(milliseconds: 50));
|
await Future.delayed(Duration(milliseconds: 50));
|
||||||
expect(
|
expect(
|
||||||
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
FakeMatrixApi.calledEndpoints.containsKey('/client/r0/keys/upload'),
|
||||||
|
|
@ -99,6 +122,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('restoreOlmSession', () async {
|
test('restoreOlmSession', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption.olmManager.olmSessions.clear();
|
||||||
await client.encryption.olmManager
|
await client.encryption.olmManager
|
||||||
.restoreOlmSession(client.userID, client.identityKey);
|
.restoreOlmSession(client.userID, client.identityKey);
|
||||||
|
|
@ -116,6 +140,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('startOutgoingOlmSessions', () async {
|
test('startOutgoingOlmSessions', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
// start an olm session.....with ourself!
|
// start an olm session.....with ourself!
|
||||||
client.encryption.olmManager.olmSessions.clear();
|
client.encryption.olmManager.olmSessions.clear();
|
||||||
await client.encryption.olmManager.startOutgoingOlmSessions(
|
await client.encryption.olmManager.startOutgoingOlmSessions(
|
||||||
|
|
@ -127,6 +152,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('replay to_device events', () async {
|
test('replay to_device events', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final userId = '@alice:example.com';
|
final userId = '@alice:example.com';
|
||||||
final deviceId = 'JLAFKJWSCS';
|
final deviceId = 'JLAFKJWSCS';
|
||||||
final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8';
|
final senderKey = 'L+4+JCl8MD63dgo8z5Ta+9QAHXiANyOVSfgbHA5d3H8';
|
||||||
|
|
@ -209,6 +235,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -30,16 +30,6 @@ void main() {
|
||||||
group('Online Key Backup', () {
|
group('Online Key Backup', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
|
|
@ -48,10 +38,21 @@ void main() {
|
||||||
final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
final senderKey = 'JBG7ZaPn54OBC7TuIEiylW3BZ+7WcGQhFBPB9pogbAg';
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('basic things', () async {
|
test('basic things', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
expect(client.encryption.keyManager.enabled, true);
|
expect(client.encryption.keyManager.enabled, true);
|
||||||
expect(await client.encryption.keyManager.isCached(), false);
|
expect(await client.encryption.keyManager.isCached(), false);
|
||||||
final handle = client.encryption.ssss.open();
|
final handle = client.encryption.ssss.open();
|
||||||
|
|
@ -61,6 +62,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('load key', () async {
|
test('load key', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client.encryption.keyManager.clearInboundGroupSessions();
|
client.encryption.keyManager.clearInboundGroupSessions();
|
||||||
await client.encryption.keyManager
|
await client.encryption.keyManager
|
||||||
.request(client.getRoomById(roomId), sessionId, senderKey);
|
.request(client.getRoomById(roomId), sessionId, senderKey);
|
||||||
|
|
@ -72,6 +74,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('upload key', () async {
|
test('upload key', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final session = olm.OutboundGroupSession();
|
final session = olm.OutboundGroupSession();
|
||||||
session.create();
|
session.create();
|
||||||
final inbound = olm.InboundGroupSession();
|
final inbound = olm.InboundGroupSession();
|
||||||
|
|
@ -115,6 +118,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -46,29 +46,31 @@ void main() {
|
||||||
group('SSSS', () {
|
group('SSSS', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
if (!olmEnabled) return;
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
|
|
||||||
test('setupClient', () async {
|
test('setupClient', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
if (!olmEnabled) return;
|
||||||
|
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('basic things', () async {
|
test('basic things', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
expect(client.encryption.ssss.defaultKeyId,
|
expect(client.encryption.ssss.defaultKeyId,
|
||||||
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3');
|
'0FajDWYaM6wQ4O60OZnLvwZfsBNu4Bu3');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('encrypt / decrypt', () {
|
test('encrypt / decrypt', () {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final key = Uint8List.fromList(SecureRandom(32).bytes);
|
final key = Uint8List.fromList(SecureRandom(32).bytes);
|
||||||
|
|
||||||
final enc = SSSS.encryptAes('secret foxies', key, 'name');
|
final enc = SSSS.encryptAes('secret foxies', key, 'name');
|
||||||
|
|
@ -77,6 +79,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('store', () async {
|
test('store', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final handle = client.encryption.ssss.open();
|
final handle = client.encryption.ssss.open();
|
||||||
var failed = false;
|
var failed = false;
|
||||||
try {
|
try {
|
||||||
|
|
@ -113,6 +116,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('encode / decode recovery key', () async {
|
test('encode / decode recovery key', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final key = Uint8List.fromList(SecureRandom(32).bytes);
|
final key = Uint8List.fromList(SecureRandom(32).bytes);
|
||||||
final encoded = SSSS.encodeRecoveryKey(key);
|
final encoded = SSSS.encodeRecoveryKey(key);
|
||||||
final decoded = SSSS.decodeRecoveryKey(encoded);
|
final decoded = SSSS.decodeRecoveryKey(encoded);
|
||||||
|
|
@ -124,6 +128,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('cache', () async {
|
test('cache', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption.ssss.clearCache();
|
||||||
final handle =
|
final handle =
|
||||||
client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning);
|
client.encryption.ssss.open(EventTypes.CrossSigningSelfSigning);
|
||||||
|
|
@ -157,6 +162,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('postUnlock', () async {
|
test('postUnlock', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.encryption.ssss.clearCache();
|
await client.encryption.ssss.clearCache();
|
||||||
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false);
|
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(false);
|
||||||
final handle =
|
final handle =
|
||||||
|
|
@ -181,6 +187,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('make share requests', () async {
|
test('make share requests', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
||||||
key.setDirectVerified(true);
|
key.setDirectVerified(true);
|
||||||
|
|
@ -193,6 +200,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('answer to share requests', () async {
|
test('answer to share requests', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
var event = ToDeviceEvent(
|
var event = ToDeviceEvent(
|
||||||
sender: client.userID,
|
sender: client.userID,
|
||||||
type: 'm.secret.request',
|
type: 'm.secret.request',
|
||||||
|
|
@ -291,6 +299,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('receive share requests', () async {
|
test('receive share requests', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
||||||
key.setDirectVerified(true);
|
key.setDirectVerified(true);
|
||||||
|
|
@ -433,6 +442,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('request all', () async {
|
test('request all', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
final key =
|
final key =
|
||||||
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
client.userDeviceKeys[client.userID].deviceKeys['OTHERDEVICE'];
|
||||||
key.setDirectVerified(true);
|
key.setDirectVerified(true);
|
||||||
|
|
@ -443,6 +453,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('periodicallyRequestMissingCache', () async {
|
test('periodicallyRequestMissingCache', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(true);
|
client.userDeviceKeys[client.userID].masterKey.setDirectVerified(true);
|
||||||
client.encryption.ssss = MockSSSS(client.encryption);
|
client.encryption.ssss = MockSSSS(client.encryption);
|
||||||
(client.encryption.ssss as MockSSSS).requestedSecrets = false;
|
(client.encryption.ssss as MockSSSS).requestedSecrets = false;
|
||||||
|
|
@ -455,6 +466,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('createKey', () async {
|
test('createKey', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
// with passphrase
|
// with passphrase
|
||||||
var newKey = await client.encryption.ssss.createKey('test');
|
var newKey = await client.encryption.ssss.createKey('test');
|
||||||
expect(client.encryption.ssss.isKeyValid(newKey.keyId), true);
|
expect(client.encryption.ssss.isKeyValid(newKey.keyId), true);
|
||||||
|
|
@ -470,6 +482,7 @@ void main() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('dispose client', () async {
|
test('dispose client', () async {
|
||||||
|
if (!olmEnabled) return;
|
||||||
await client.dispose(closeDatabase: true);
|
await client.dispose(closeDatabase: true);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -35,14 +35,6 @@ void main() {
|
||||||
group('Event', () {
|
group('Event', () {
|
||||||
Logs().level = Level.error;
|
Logs().level = Level.error;
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
final timestamp = DateTime.now().millisecondsSinceEpoch;
|
final timestamp = DateTime.now().millisecondsSinceEpoch;
|
||||||
final id = '!4fsdfjisjf:server.abc';
|
final id = '!4fsdfjisjf:server.abc';
|
||||||
|
|
@ -68,6 +60,17 @@ void main() {
|
||||||
var event = Event.fromJson(
|
var event = Event.fromJson(
|
||||||
jsonObj, Room(id: '!localpart:server.abc', client: client));
|
jsonObj, Room(id: '!localpart:server.abc', client: client));
|
||||||
|
|
||||||
|
test('setup', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
|
});
|
||||||
|
|
||||||
test('Create from json', () async {
|
test('Create from json', () async {
|
||||||
jsonObj.remove('status');
|
jsonObj.remove('status');
|
||||||
jsonObj['content'] = json.decode(contentJson);
|
jsonObj['content'] = json.decode(contentJson);
|
||||||
|
|
|
||||||
|
|
@ -35,19 +35,19 @@ void main() {
|
||||||
var updateCount = 0;
|
var updateCount = 0;
|
||||||
var insertList = <int>[];
|
var insertList = <int>[];
|
||||||
var olmEnabled = true;
|
var olmEnabled = true;
|
||||||
try {
|
|
||||||
olm.init();
|
|
||||||
olm.Account();
|
|
||||||
} catch (e) {
|
|
||||||
olmEnabled = false;
|
|
||||||
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
|
||||||
}
|
|
||||||
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
|
||||||
|
|
||||||
Client client;
|
Client client;
|
||||||
Room room;
|
Room room;
|
||||||
Timeline timeline;
|
Timeline timeline;
|
||||||
test('create stuff', () async {
|
test('create stuff', () async {
|
||||||
|
try {
|
||||||
|
await olm.init();
|
||||||
|
olm.get_library_version();
|
||||||
|
} catch (e) {
|
||||||
|
olmEnabled = false;
|
||||||
|
Logs().w('[LibOlm] Failed to load LibOlm', e);
|
||||||
|
}
|
||||||
|
Logs().i('[LibOlm] Enabled: $olmEnabled');
|
||||||
client = await getClient();
|
client = await getClient();
|
||||||
client.sendMessageTimeoutSeconds = 5;
|
client.sendMessageTimeoutSeconds = 5;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue