diff --git a/lib/src/helpers.dart b/lib/src/helpers.dart index 86f8df1..a99531f 100644 --- a/lib/src/helpers.dart +++ b/lib/src/helpers.dart @@ -52,19 +52,6 @@ class ListDiff { final List removed; } -extension BeforeAfterListDiff on List { - /// Compute the set-based changes between this list and [newList]. - ListDiff diff(List newList) { - final oldSet = Set.from(this); - final newSet = Set.from(newList); - - return ListDiff( - newSet.difference(oldSet).toList(), - oldSet.difference(newSet).toList(), - ); - } -} - extension AppendToListOrCreateExtension on Map> { /// Create or append [value] to the list identified with key [key]. void appendOrCreate(K key, V value, {bool checkExistence = false}) { diff --git a/lib/src/omemo/omemo.dart b/lib/src/omemo/omemo.dart index 6ed6e7d..1a7fef5 100644 --- a/lib/src/omemo/omemo.dart +++ b/lib/src/omemo/omemo.dart @@ -60,19 +60,16 @@ typedef DeviceListSubscribeFunction = Future Function(String jid); /// Publishes the device bundle on our own PEP node. typedef PublishDeviceBundleFunction = Future Function(OmemoDevice device); -/// Commits the device list for [jid] to persistent storage. [added] will be the list of -/// devices added and [removed] will be the list of removed devices. +/// Commits the device list [devices] for [jid] to persistent storage. typedef CommitDeviceListCallback = Future Function( String jid, - List added, - List removed, + List devices, ); /// A stub implementation of [CommitDeviceListCallback]. Future commitDeviceListStub( String _, List __, - List ___, ) async {} /// Commits the mapping of the (new) ratchets in [ratchets] to persistent storage. @@ -262,7 +259,6 @@ class OmemoManager { await commitDeviceList( jid, newDeviceList, - [], ); } } @@ -866,7 +862,6 @@ class OmemoManager { await commitDeviceList( jid, [], - _deviceList[jid]!, ); _deviceList.remove(jid); _deviceListRequested.remove(jid); @@ -880,20 +875,12 @@ class OmemoManager { await _ratchetQueue.synchronized( [jid], () async { - // Compute the delta - ListDiff delta; - if (_deviceList.containsKey(jid)) { - delta = _deviceList[jid]!.diff(devices); - } else { - delta = ListDiff(devices, []); - } - // Update our state _deviceList[jid] = devices; _deviceListRequested[jid] = true; // Commit the device list - await commitDeviceList(jid, delta.added, delta.removed); + await commitDeviceList(jid, devices); }, ); } @@ -1013,6 +1000,31 @@ class OmemoManager { }); } + /// Generates a completely new device to use. + Future regenerateDevice() async { + // Generate the new device + final oldDevice = await getDevice(); + final newDevice = await OmemoDevice.generateNewDevice( + oldDevice.jid, + opkAmount: oldDevice.opks.length, + ); + + await _deviceLock.synchronized(() async { + // Replace the old device + _device = newDevice; + + // Commit + await commitDevice(newDevice); + + // Publish + unawaited( + publishDeviceBundle(newDevice), + ); + }); + + return newDevice; + } + /// Acquire a lock for interacting with the trust manager for modifying the trust /// state of [jid]. [callback] is called from within the critical section with the /// trust manager as its parameter. diff --git a/lib/src/trust/btbv.dart b/lib/src/trust/btbv.dart index 5a04ab8..5d45aca 100644 --- a/lib/src/trust/btbv.dart +++ b/lib/src/trust/btbv.dart @@ -10,6 +10,7 @@ class BTBVTrustData { this.device, this.state, this.enabled, + this.trusted, ); /// The JID in question. @@ -23,6 +24,12 @@ class BTBVTrustData { /// Flag indicating whether the ratchet is enabled (true) or not (false). final bool enabled; + + /// Flag indicating whether the ratchet is trusted. For loading and commiting a ratchet, this field + /// contains an arbitrary value. + /// When using [BlindTrustBeforeVerificationTrustManager.getDevicesTrust], this flag will be true if + /// the ratchet is trusted and false if not. + final bool trusted; } /// A callback for when a trust decision is to be commited to persistent storage. @@ -54,6 +61,20 @@ enum BTBVTrustState { const BTBVTrustState(this.value); + factory BTBVTrustState.fromInt(int value) { + switch (value) { + case 1: + return BTBVTrustState.notTrusted; + case 2: + return BTBVTrustState.blindTrust; + case 3: + return BTBVTrustState.verified; + // TODO(Unknown): Should we handle this better? + default: + return BTBVTrustState.notTrusted; + } + } + /// The value backing the trust state. final int value; } @@ -142,19 +163,31 @@ class BlindTrustBeforeVerificationTrustManager extends TrustManager { deviceId, trustCache[key]!, enablementCache[key]!, + false, ), ); } /// Returns a mapping from the device identifiers of [jid] to their trust state. If /// there are no devices known for [jid], then an empty map is returned. - Future> getDevicesTrust(String jid) async { - final map = {}; + Future> getDevicesTrust(String jid) async { + final map = {}; if (!devices.containsKey(jid)) return map; for (final deviceId in devices[jid]!) { - map[deviceId] = trustCache[RatchetMapKey(jid, deviceId)]!; + final key = RatchetMapKey(jid, deviceId); + if (!trustCache.containsKey(key) || !enablementCache.containsKey(key)) { + continue; + } + + map[deviceId] = BTBVTrustData( + jid, + deviceId, + trustCache[key]!, + enablementCache[key]!, + await isTrusted(jid, deviceId), + ); } return map; @@ -176,6 +209,7 @@ class BlindTrustBeforeVerificationTrustManager extends TrustManager { deviceId, state, enablementCache[key]!, + false, ), ); } @@ -200,6 +234,7 @@ class BlindTrustBeforeVerificationTrustManager extends TrustManager { deviceId, trustCache[key]!, enabled, + false, ), ); } diff --git a/test/helpers_test.dart b/test/helpers_test.dart deleted file mode 100644 index 0b718d2..0000000 --- a/test/helpers_test.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'package:omemo_dart/src/helpers.dart'; -import 'package:omemo_dart/src/omemo/queue.dart'; -import 'package:test/test.dart'; - -void main() { - group('List diff', () { - test('Empty list to full list', () { - final result = [].diff([1, 2, 3, 4]); - expect(result.removed, isEmpty); - expect( - result.added.containsAll([1, 2, 3, 4]), - isTrue, - ); - expect(result.added.length, 4); - }); - - test('Full list to empty list', () { - final result = [1, 2, 3, 4].diff([]); - expect(result.added, isEmpty); - expect( - result.removed.containsAll([1, 2, 3, 4]), - isTrue, - ); - expect(result.removed.length, 4); - }); - - test('Full list to full list', () { - final result = [1, 2, 3, 4].diff([1, 2, 4, 5]); - expect(result.added, [5]); - expect(result.removed, [3]); - }); - }); -}