diff --git a/lib/ops/keyserver-store-ops.js b/lib/ops/keyserver-store-ops.js --- a/lib/ops/keyserver-store-ops.js +++ b/lib/ops/keyserver-store-ops.js @@ -129,4 +129,7 @@ }, }; -export { keyserverStoreOpsHandlers }; +export { + keyserverStoreOpsHandlers, + convertKeyserverInfoToClientDBKeyserverInfo, +}; diff --git a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/DatabaseQueryExecutor.h @@ -2,6 +2,7 @@ #include "../CryptoTools/Persist.h" #include "entities/Draft.h" +#include "entities/KeyserverInfo.h" #include "entities/Media.h" #include "entities/Message.h" #include "entities/MessageStoreThread.h" @@ -67,6 +68,10 @@ virtual void removeUsers(const std::vector &ids) const = 0; virtual void removeAllUsers() const = 0; virtual std::vector getAllUsers() const = 0; + virtual void replaceKeyserver(const KeyserverInfo &keyserver_info) const = 0; + virtual void removeKeyservers(const std::vector &ids) const = 0; + virtual void removeAllKeyservers() const = 0; + virtual std::vector getAllKeyservers() const = 0; virtual void beginTransaction() const = 0; virtual void commitTransaction() const = 0; virtual void rollbackTransaction() const = 0; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.h @@ -3,6 +3,7 @@ #include "../CryptoTools/Persist.h" #include "DatabaseQueryExecutor.h" #include "entities/Draft.h" +#include "entities/KeyserverInfo.h" #include "entities/UserInfo.h" #include @@ -71,6 +72,10 @@ void removeUsers(const std::vector &ids) const override; void removeAllUsers() const override; std::vector getAllUsers() const override; + void replaceKeyserver(const KeyserverInfo &keyserver_info) const override; + void removeKeyservers(const std::vector &ids) const override; + void removeAllKeyservers() const override; + std::vector getAllKeyservers() const override; void beginTransaction() const override; void commitTransaction() const override; void rollbackTransaction() const override; diff --git a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp --- a/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp +++ b/native/cpp/CommonCpp/DatabaseManagers/SQLiteQueryExecutor.cpp @@ -2,6 +2,7 @@ #include "Logger.h" #include "sqlite_orm.h" +#include "entities/KeyserverInfo.h" #include "entities/Metadata.h" #include "entities/UserInfo.h" #include @@ -981,7 +982,11 @@ make_table( "users", make_column("id", &UserInfo::id, unique(), primary_key()), - make_column("user_info", &UserInfo::user_info)) + make_column("user_info", &UserInfo::user_info)), + make_table( + "keyservers", + make_column("id", &KeyserverInfo::id, unique(), primary_key()), + make_column("keyserver_info", &KeyserverInfo::keyserver_info)) ); storage.on_open = on_open_callback; @@ -1323,6 +1328,25 @@ where(in(&UserInfo::id, ids))); } +void SQLiteQueryExecutor::replaceKeyserver( + const KeyserverInfo &keyserver_info) const { + SQLiteQueryExecutor::getStorage().replace(keyserver_info); +} + +void SQLiteQueryExecutor::removeAllKeyservers() const { + SQLiteQueryExecutor::getStorage().remove_all(); +} + +void SQLiteQueryExecutor::removeKeyservers( + const std::vector &ids) const { + SQLiteQueryExecutor::getStorage().remove_all( + where(in(&KeyserverInfo::id, ids))); +} + +std::vector SQLiteQueryExecutor::getAllKeyservers() const { + return SQLiteQueryExecutor::getStorage().get_all(); +} + std::vector SQLiteQueryExecutor::getAllUsers() const { return SQLiteQueryExecutor::getStorage().get_all(); } diff --git a/native/cpp/CommonCpp/DatabaseManagers/entities/KeyserverInfo.h b/native/cpp/CommonCpp/DatabaseManagers/entities/KeyserverInfo.h new file mode 100644 --- /dev/null +++ b/native/cpp/CommonCpp/DatabaseManagers/entities/KeyserverInfo.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +namespace comm { + +struct KeyserverInfo { + std::string id; + std::string keyserver_info; +}; + +} // namespace comm diff --git a/web/cpp/SQLiteQueryExecutorBindings.cpp b/web/cpp/SQLiteQueryExecutorBindings.cpp --- a/web/cpp/SQLiteQueryExecutorBindings.cpp +++ b/web/cpp/SQLiteQueryExecutorBindings.cpp @@ -39,6 +39,9 @@ value_object("UserInfo") .field("id", &UserInfo::id) .field("userInfo", &UserInfo::user_info); + value_object("KeyserverInfo") + .field("id", &KeyserverInfo::id) + .field("keyserverInfo", &KeyserverInfo::keyserver_info); value_object("WebThread") .field("id", &WebThread::id) @@ -86,6 +89,11 @@ .function("getAllThreadsWeb", &SQLiteQueryExecutor::getAllThreadsWeb) .function("removeAllThreads", &SQLiteQueryExecutor::removeAllThreads) .function("removeThreads", &SQLiteQueryExecutor::removeThreads) + .function("replaceKeyserver", &SQLiteQueryExecutor::replaceKeyserver) + .function("removeKeyservers", &SQLiteQueryExecutor::removeKeyservers) + .function( + "removeAllKeyservers", &SQLiteQueryExecutor::removeAllKeyservers) + .function("getAllKeyservers", &SQLiteQueryExecutor::getAllKeyservers) .function("beginTransaction", &SQLiteQueryExecutor::beginTransaction) .function("commitTransaction", &SQLiteQueryExecutor::commitTransaction) .function( diff --git a/web/database/_generated/comm-query-executor.js b/web/database/_generated/comm-query-executor.js --- a/web/database/_generated/comm-query-executor.js +++ b/web/database/_generated/comm-query-executor.js @@ -117,7 +117,7 @@ V.prototype.fromWireType=function(a){function b(){return this.Ub?Jb(this.Sa.Db,{Wa:this.Ld,Ra:c,eb:this,$a:a}):Jb(this.Sa.Db,{Wa:this,Ra:a})}var c=this.wd(a);if(!c)return this.Gc(a),null;var d=Ib(this.Sa,c);if(void 0!==d){if(0===d.Ma.count.value)return d.Ma.Ra=c,d.Ma.$a=a,d.clone();d=d.clone();this.Gc(a);return d}d=this.Sa.ud(c);d=Db[d];if(!d)return b.call(this);d=this.Sb?d.hd:d.pointerType;var f=Cb(c,this.Sa,d.Sa);return null===f?b.call(this):this.Ub?Jb(d.Sa.Db,{Wa:d,Ra:f,eb:this,$a:a}):Jb(d.Sa.Db, {Wa:d,Ra:f})};Wb=e.UnboundTypeError=rb("UnboundTypeError");e.count_emval_handles=function(){for(var a=0,b=5;bf?-28:N.Ec(d,f).fd;case 1:case 2:return 0;case 3:return d.flags;case 4:return f=hb(),d.flags|=f,0;case 5:return f=hb(),D[f+0>>1]=2,0;case 6:case 7:return 0;case 16:case 8:return-28;case 9:return E[Kc()>>2]=28,-1;default:return-28}}catch(g){if("undefined"== +b),0}catch(c){if("undefined"==typeof N||!(c instanceof N.La))throw c;return-c.Qa}},Y:function(a,b,c){try{return N.fchown(a,b,c),0}catch(d){if("undefined"==typeof N||!(d instanceof N.La))throw d;return-d.Qa}},f:function(a,b,c){gb=c;try{var d=Q(a);switch(b){case 0:var f=hb();return 0>f?-28:N.Ec(d,f).fd;case 1:case 2:return 0;case 3:return d.flags;case 4:return f=hb(),d.flags|=f,0;case 5:return f=hb(),D[f+0>>1]=2,0;case 6:case 7:return 0;case 16:case 8:return-28;case 9:return E[Kc()>>2]=28,-1;default:return-28}}catch(g){if("undefined"== typeof N||!(g instanceof N.La))throw g;return-g.Qa}},W:function(a,b){try{var c=Q(a);return fb(N.stat,c.path,b)}catch(d){if("undefined"==typeof N||!(d instanceof N.La))throw d;return-d.Qa}},B:function(a,b,c){try{b=c+2097152>>>0<4194305-!!b?(b>>>0)+4294967296*c:NaN;if(isNaN(b))return-61;N.td(a,b);return 0}catch(d){if("undefined"==typeof N||!(d instanceof N.La))throw d;return-d.Qa}},R:function(a,b){try{if(0===b)return-28;var c=N.cwd(),d=ta(c)+1;if(b>>0,(G=h,1<=+Math.abs(G)?0>>0:~~+Math.ceil((G-+(~~G>>>0))/4294967296)>>> 0:0)];E[b+a>>2]=J[0];E[b+a+4>>2]=J[1];J=[280*(g+1)>>>0,(G=280*(g+1),1<=+Math.abs(G)?0>>0:~~+Math.ceil((G-+(~~G>>>0))/4294967296)>>>0:0)];E[b+a+8>>2]=J[0];E[b+a+12>>2]=J[1];D[b+a+16>>1]=280;B[b+a+18>>0]=n;A(k,z,b+a+19,256);a+=280;g+=1}N.ab(d,280*g,0);return a}catch(p){if("undefined"==typeof N||!(p instanceof N.La))throw p;return-p.Qa}},X:function(a,b,c){gb=c;try{var d=Q(a);switch(b){case 21509:case 21505:return d.tty?0:-59;case 21510:case 21511:case 21512:case 21506:case 21507:case 21508:return d.tty? @@ -135,7 +135,7 @@ h=>h;if(0===d){var k=32-8*c;g=h=>h<>>k}c=b.includes("unsigned")?function(h,n){return n>>>0}:function(h,n){return n};R(a,{name:b,fromWireType:g,toWireType:c,argPackAdvance:8,readValueFromPointer:gc(b,f,0!==d),hb:null})},c:function(a,b,c){function d(g){g>>=2;var k=F;return new f(ua,k[g+1],k[g])}var f=[Int8Array,Uint8Array,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array][b];c=S(c);R(a,{name:c,fromWireType:d,argPackAdvance:8,readValueFromPointer:d},{zd:!0})},w:function(a,b){b= S(b);var c="std::string"===b;R(a,{name:b,fromWireType:function(d){var f=F[d>>2],g=d+4;if(c)for(var k=g,h=0;h<=f;++h){var n=g+h;if(h==f||0==z[n]){k=y(k,n-k);if(void 0===q)var q=k;else q+=String.fromCharCode(0),q+=k;k=n+1}}else{q=Array(f);for(h=0;h>2]=k;if(c&&g)A(f,z,n,k+1);else if(g)for(g=0;gva;var h=1}else 4===b&&(d=lc,f=mc,g=nc,k=()=>F,h=2);R(a,{name:c,fromWireType:function(n){for(var q= -F[n>>2],p=k(),t,x=n+4,l=0;l<=q;++l){var u=n+4+l*b;if(l==q||0==p[u>>h])x=d(x,u-x),void 0===t?t=x:(t+=String.fromCharCode(0),t+=x),x=u+b}X(n);return t},toWireType:function(n,q){"string"!=typeof q&&T("Cannot pass non-string to C++ string type "+c);var p=g(q),t=wc(4+p+b);F[t>>2]=p>>h;f(q,t+4,p+b);null!==n&&n.push(X,t);return t},argPackAdvance:8,readValueFromPointer:lb,hb:function(n){X(n)}})},i:function(a,b,c,d,f,g){jb[a]={name:S(b),qc:W(c,d),ob:W(f,g),Kc:[]}},f:function(a,b,c,d,f,g,k,h,n,q){jb[a].Kc.push({qd:S(b), +F[n>>2],p=k(),t,x=n+4,l=0;l<=q;++l){var u=n+4+l*b;if(l==q||0==p[u>>h])x=d(x,u-x),void 0===t?t=x:(t+=String.fromCharCode(0),t+=x),x=u+b}X(n);return t},toWireType:function(n,q){"string"!=typeof q&&T("Cannot pass non-string to C++ string type "+c);var p=g(q),t=wc(4+p+b);F[t>>2]=p>>h;f(q,t+4,p+b);null!==n&&n.push(X,t);return t},argPackAdvance:8,readValueFromPointer:lb,hb:function(n){X(n)}})},i:function(a,b,c,d,f,g){jb[a]={name:S(b),qc:W(c,d),ob:W(f,g),Kc:[]}},e:function(a,b,c,d,f,g,k,h,n,q){jb[a].Kc.push({qd:S(b), yd:c,Rb:W(d,f),xd:g,Rd:k,Qd:W(h,n),Sd:q})},fa:function(a,b){b=S(b);R(a,{Cd:!0,name:b,argPackAdvance:0,fromWireType:function(){},toWireType:function(){}})},n:function(){return Date.now()},$:function(){return!0},x:function(a,b,c){a=ec(a);b=oc(b,"emval::as");var d=[],f=Sb(d);F[c>>2]=f;return b.toWireType(d,a)},ma:function(a,b,c,d){a=rc[a];b=ec(b);c=qc(c);a(b,c,null,d)},ka:dc,la:function(a,b){var c=tc(a,b),d=c[0];b=d.name+"_$"+c.slice(1).map(function(p){return p.name}).join("_")+"$";var f=uc[b];if(void 0!== f)return f;f=["retType"];for(var g=[d],k="",h=0;h>2]=a.getSeconds();E[b+4>>2]=a.getMinutes();E[b+8>>2]=a.getHours();E[b+12>>2]=a.getDate();E[b+16>>2]=a.getMonth();E[b+20>>2]= diff --git a/web/database/_generated/comm_query_executor.wasm b/web/database/_generated/comm_query_executor.wasm index 0000000000000000000000000000000000000000..0000000000000000000000000000000000000000 GIT binary patch literal 0 Hc$@ { + let queryExecutor: ?SQLiteQueryExecutor = null; + let dbModule: ?EmscriptenModule = null; + + beforeAll(async () => { + dbModule = getDatabaseModule(); + }); + + beforeEach(() => { + if (!dbModule) { + return; + } + queryExecutor = new dbModule.SQLiteQueryExecutor(FILE_PATH); + queryExecutor?.replaceKeyserver( + convertKeyserverInfoToClientDBKeyserverInfo({ + keyserverInfo: TEST_KEYSERVER_1, + id: '1', + }), + ); + queryExecutor?.replaceKeyserver( + convertKeyserverInfoToClientDBKeyserverInfo({ + keyserverInfo: TEST_KEYSERVER_2, + id: '2', + }), + ); + }); + + afterEach(() => { + if (!dbModule || !queryExecutor) { + return; + } + clearSensitiveData(dbModule, FILE_PATH, queryExecutor); + }); + + it('should return all keyservers', () => { + const keyservers = queryExecutor?.getAllKeyservers(); + expect(keyservers?.length).toBe(2); + }); + + it('should remove all keyservers', () => { + queryExecutor?.removeAllKeyservers(); + const keyservers = queryExecutor?.getAllKeyservers(); + expect(keyservers?.length).toBe(0); + }); + + it('should update keyserver cookie', () => { + const keyserver2Updated: KeyserverInfo = { + ...TEST_KEYSERVER_1, + cookie: 'updatedCookie', + }; + + queryExecutor?.replaceKeyserver( + convertKeyserverInfoToClientDBKeyserverInfo({ + keyserverInfo: keyserver2Updated, + id: '1', + }), + ); + + const keyservers = queryExecutor?.getAllKeyservers(); + if (!keyservers) { + throw new Error('keyservers not defined'); + } + expect(keyservers.length).toBe(2); + + const keyserversFromDB = + keyserverStoreOpsHandlers.translateClientDBData(keyservers); + expect(keyserversFromDB['1']).toBeDefined(); + expect(keyserversFromDB['1'].cookie).toBe('updatedCookie'); + }); + + it('should remove keyserver', () => { + queryExecutor?.removeKeyservers(['1']); + + const keyservers = queryExecutor?.getAllKeyservers(); + if (!keyservers) { + throw new Error('keyservers not defined'); + } + expect(keyservers.length).toBe(1); + + const keyserversFromDB = + keyserverStoreOpsHandlers.translateClientDBData(keyservers); + expect(keyserversFromDB['2']).toBeDefined(); + }); +}); diff --git a/web/database/types/sqlite-query-executor.js b/web/database/types/sqlite-query-executor.js --- a/web/database/types/sqlite-query-executor.js +++ b/web/database/types/sqlite-query-executor.js @@ -1,5 +1,6 @@ // @flow +import type { ClientDBKeyserverInfo } from 'lib/ops/keyserver-store-ops.js'; import type { ClientDBReport } from 'lib/ops/report-store-ops.js'; import type { ClientDBUserInfo } from 'lib/ops/user-store-ops.js'; import type { ClientDBDraftInfo } from 'lib/types/draft-types.js'; @@ -37,6 +38,11 @@ removeAllThreads(): void; getAllThreadsWeb(): WebClientDBThreadInfo[]; + replaceKeyserver(user_info: ClientDBKeyserverInfo): void; + removeKeyservers(ids: $ReadOnlyArray): void; + removeAllKeyservers(): void; + getAllKeyservers(): ClientDBKeyserverInfo[]; + beginTransaction(): void; commitTransaction(): void; rollbackTransaction(): void;