| author | Matthew Wild
<mwild1@gmail.com> 2025-05-24 14:54:28 UTC |
| committer | Stephen Paul Weber
<singpolyma@singpolyma.net> 2025-09-29 13:43:29 UTC |
| parent | fb924042cc760e02e538b2b287c7086abfcaebdc |
| 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 }