From 7d0a4dc3bc13bc9b9421b0640f422b88941ddef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20Ku=C3=9Fowski?= Date: Fri, 22 Aug 2025 14:01:28 +0200 Subject: [PATCH] refactor: Make signableJson type safe with type safe class --- lib/encryption/olm_manager.dart | 50 ++++++++++++++++----------- lib/encryption/utils/olm_session.dart | 15 ++++---- 2 files changed, 38 insertions(+), 27 deletions(-) diff --git a/lib/encryption/olm_manager.dart b/lib/encryption/olm_manager.dart index 9b41d3c7..2176aee2 100644 --- a/lib/encryption/olm_manager.dart +++ b/lib/encryption/olm_manager.dart @@ -102,28 +102,17 @@ class OlmManager { /// Adds a signature to this json from this olm account and returns the signed /// json. - Map signJson(Map payload) { + Map signJson(Map payload) { if (!enabled) throw ('Encryption is disabled'); - final Map? unsigned = payload['unsigned']; - final Map? signatures = payload['signatures']; - payload.remove('unsigned'); - payload.remove('signatures'); - final canonical = canonicalJson.encode(payload); + final signableJson = SignableJsonMap(payload); + + final canonical = canonicalJson.encode(signableJson.jsonMap); final signature = _olmAccount!.sign(String.fromCharCodes(canonical)); - if (signatures != null) { - payload['signatures'] = signatures; - } else { - payload['signatures'] = {}; - } - if (!payload['signatures'].containsKey(client.userID)) { - payload['signatures'][client.userID] = {}; - } - payload['signatures'][client.userID]['ed25519:$ourDeviceId'] = - signature.toBase64(); - if (unsigned != null) { - payload['unsigned'] = unsigned; - } - return payload; + + final userSignatures = signableJson.signatures[client.userID!] ??= {}; + userSignatures['ed25519:$ourDeviceId'] = signature.toBase64(); + + return signableJson.toJson(); } String signString(String s) { @@ -811,3 +800,24 @@ class NoOlmSessionFoundException implements Exception { String toString() => 'No olm session found for ${device.userId}:${device.deviceId}'; } + +class SignableJsonMap { + final Map jsonMap; + final Map> signatures; + final Map? unsigned; + + SignableJsonMap(Map json) + : jsonMap = json, + signatures = + json.tryGetMap>('signatures') ?? {}, + unsigned = json.tryGetMap('unsigned') { + jsonMap.remove('signatures'); + jsonMap.remove('unsigned'); + } + + Map toJson() => { + ...jsonMap, + 'signatures': signatures, + if (unsigned != null) 'unsigned': unsigned, + }; +} diff --git a/lib/encryption/utils/olm_session.dart b/lib/encryption/utils/olm_session.dart index 6c5a385c..7be42ea2 100644 --- a/lib/encryption/utils/olm_session.dart +++ b/lib/encryption/utils/olm_session.dart @@ -41,24 +41,25 @@ class OlmSession { required this.lastReceived, }); - OlmSession.fromJson(Map dbEntry, this.key) - : identityKey = dbEntry['identity_key'] ?? '' { + OlmSession.fromJson(Map dbEntry, this.key) + : identityKey = dbEntry.tryGet('identity_key') ?? '' { try { try { session = vod.Session.fromPickleEncrypted( pickleKey: key.toPickleKey(), - pickle: dbEntry['pickle'], + pickle: dbEntry['pickle'] as String, ); } catch (_) { Logs().d('Unable to unpickle Olm session. Try LibOlm format.'); session = vod.Session.fromOlmPickleEncrypted( pickleKey: utf8.encode(key), - pickle: dbEntry['pickle'], + pickle: dbEntry['pickle'] as String, ); } - sessionId = dbEntry['session_id']; - lastReceived = - DateTime.fromMillisecondsSinceEpoch(dbEntry['last_received'] ?? 0); + sessionId = dbEntry['session_id'] as String; + lastReceived = DateTime.fromMillisecondsSinceEpoch( + dbEntry.tryGet('last_received') ?? 0, + ); assert(sessionId == session!.sessionId); } catch (e, s) { Logs().e('[Vodozemac] Could not unpickle olm session', e, s);