git » sdk » commit b860690

OMEMO: Add OMEMO session metadata storage (IDB only)

author Matthew Wild
2025-05-24 14:54:28 UTC
committer Stephen Paul Weber
2025-09-29 13:43:29 UTC
parent fb924042cc760e02e538b2b287c7086abfcaebdc

OMEMO: Add OMEMO session metadata storage (IDB only)

snikket/OMEMO.hx +17 -0
snikket/Persistence.hx +3 -0
snikket/persistence/Dummy.hx +7 -0
snikket/persistence/IDB.js +38 -0
snikket/persistence/Sqlite.hx +12 -0

diff --git a/snikket/OMEMO.hx b/snikket/OMEMO.hx
index b366cdb..d750829 100644
--- a/snikket/OMEMO.hx
+++ b/snikket/OMEMO.hx
@@ -318,6 +318,23 @@ class OMEMODecryptionResult {
 	}
 }
 
+class OMEMOSessionMetadata {
+	// True when we have successfully received and decrypted any
+	// non-prekey message from this session
+	public final receivedSessionMessageOk:Bool;
+	// True if the last message we received from this session
+	// was successfully decrypted
+	public final lastMessageDecryptedOk:Bool;
+	// True if we have sent a key exchange to repair this session
+	public final sentKeyExchange:Bool;
+
+	public function new(receivedSessionMessageOk:Bool, lastMessageDecryptedOk:Bool, sentKeyExchange:Bool) {
+		this.receivedSessionMessageOk = receivedSessionMessageOk;
+		this.lastMessageDecryptedOk = lastMessageDecryptedOk;
+		this.sentKeyExchange = sentKeyExchange;
+	}
+}
+
 //@:nullSafety(Strict)
 class OMEMO {
 	private final client: Client;
diff --git a/snikket/Persistence.hx b/snikket/Persistence.hx
index 3c94c7b..6068cf5 100644
--- a/snikket/Persistence.hx
+++ b/snikket/Persistence.hx
@@ -57,6 +57,9 @@ interface Persistence {
 	public function getOmemoContactIdentityKey(account:String, address:String, callback:(IdentityPublicKey)->Void):Void;
 	public function getOmemoSession(account:String, address:String, callback:(SignalSession)->Void):Void;
 	public function storeOmemoSession(account:String, address:String, session:SignalSession):Void;
+	public function removeOmemoSession(account:String, address:String):Void;
+	public function storeOmemoMetadata(account:String, address:String, metadata:OMEMOSessionMetadata):Void;
+	public function getOmemoMetadata(account:String, address:String, callback:(OMEMOSessionMetadata)->Void):Void;
 #end
 
 
diff --git a/snikket/persistence/Dummy.hx b/snikket/persistence/Dummy.hx
index 1928870..be73c39 100644
--- a/snikket/persistence/Dummy.hx
+++ b/snikket/persistence/Dummy.hx
@@ -181,5 +181,12 @@ class Dummy implements Persistence {
 	public function getOmemoSession(account:String, address:String, callback:(SignalSession)->Void):Void { }
 	@HaxeCBridge.noemit
 	public function storeOmemoSession(account:String, address:String, session:SignalSession):Void { }
+	@HaxeCBridge.noemit
+	public function removeOmemoSession(account:String, address:String):Void { }
+	@HaxeCBridge.noemit
+	public function storeOmemoMetadata(account:String, address:String, metadata:OMEMOSessionMetadata):Void { }
+	@HaxeCBridge.noemit
+	public function getOmemoMetadata(account:String, address:String, callback:(OMEMOSessionMetadata)->Void):Void { }
+
 #end
 }
diff --git a/snikket/persistence/IDB.js b/snikket/persistence/IDB.js
index 966f06e..7ff77bf 100644
--- a/snikket/persistence/IDB.js
+++ b/snikket/persistence/IDB.js
@@ -59,6 +59,9 @@ export default (dbname, media, tokenize, stemmer) => {
 			if (!db.objectStoreNames.contains("omemo_sessions")) {
 				upgradeDb.createObjectStore("omemo_sessions", { keyPath: ["account", "address"] });
 			}
+			if (!db.objectStoreNames.contains("omemo_sessions_meta")) {
+				upgradeDb.createObjectStore("omemo_sessions_meta", { keyPath: ["account", "address"] });
+			}
 		};
 		dbOpenReq.onsuccess = (event) => {
 			db = event.target.result;
@@ -71,6 +74,7 @@ export default (dbname, media, tokenize, stemmer) => {
 				"reactions",
 				"omemo_identities",
 				"omemo_sessions",
+				"omemo_sessions_meta"
 			];
 			for(let storeName of storeNames) {
 				if(!db.objectStoreNames.contains(storeName)) {
@@ -974,6 +978,40 @@ export default (dbname, media, tokenize, stemmer) => {
 			});
 		},
 
+		storeOmemoMetadata: function (account, address, metadata) {
+			const tx = db.transaction(["omemo_sessions_meta"], "readwrite");
+			const store = tx.objectStore("omemo_sessions_meta");
+			promisifyRequest(store.put({
+				account: account,
+				address: address,
+				metadata: metadata,
+			})).catch((e) => {
+				console.error("Failed to store OMEMO session metadata: " + e);
+			});
+		},
+
+		getOmemoMetadata: function (account, address, callback) {
+			const tx = db.transaction(["omemo_sessions_meta"], "readonly");
+			const store = tx.objectStore("omemo_sessions_meta");
+			promisifyRequest(store.get([account, address])).then((result) => {
+				if(!result) {
+					callback(undefined);
+				} else {
+					callback(result.metadata);
+				}
+			}).catch((e) => {
+				console.error("Failed to load OMEMO session: " + e);
+			});
+		},
+
+		removeOmemoSession: function (account, address) {
+			// Remove session and any stored metadata
+			const tx = db.transaction(["omemo_sessions", "omemo_sessions_meta"], "readwrite");
+			const path = [account, address];
+			tx.objectStore("omemo_sessions").delete(path);
+			tx.objectStore("omemo_sessions_meta").delete(path);
+		},
+
 		get(k) {
 			const tx = db.transaction(["keyvaluepairs"], "readonly");
 			const store = tx.objectStore("keyvaluepairs");
diff --git a/snikket/persistence/Sqlite.hx b/snikket/persistence/Sqlite.hx
index 73aede4..e11c94e 100644
--- a/snikket/persistence/Sqlite.hx
+++ b/snikket/persistence/Sqlite.hx
@@ -897,5 +897,17 @@ class Sqlite implements Persistence implements KeyValueStore {
 
 	@HaxeCBridge.noemit
 	public function storeOmemoSession(account:String, address:String, session:SignalSession):Void { }
+
+	@HaxeCBridge.noemit
+	public function removeOmemoSession(account:String, address:String):Void { }
+
+	@HaxeCBridge.noemit
+	public function storeOmemoMetadata(account:String, address:String, metadata:OMEMOSessionMetadata):Void { }
+
+	@HaxeCBridge.noemit
+	public function getOmemoMetadata(account:String, address:String, callback:(OMEMOSessionMetadata)->Void):Void { }
+
+
+
 #end
 }