Page MenuHomePhabricator

D10775.diff
No OneTemporary

D10775.diff

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<std::string> &ids) const = 0;
virtual void removeAllUsers() const = 0;
virtual std::vector<UserInfo> getAllUsers() const = 0;
+ virtual void replaceKeyserver(const KeyserverInfo &keyserver_info) const = 0;
+ virtual void removeKeyservers(const std::vector<std::string> &ids) const = 0;
+ virtual void removeAllKeyservers() const = 0;
+ virtual std::vector<KeyserverInfo> 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 <mutex>
@@ -71,6 +72,10 @@
void removeUsers(const std::vector<std::string> &ids) const override;
void removeAllUsers() const override;
std::vector<UserInfo> getAllUsers() const override;
+ void replaceKeyserver(const KeyserverInfo &keyserver_info) const override;
+ void removeKeyservers(const std::vector<std::string> &ids) const override;
+ void removeAllKeyservers() const override;
+ std::vector<KeyserverInfo> 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 <fstream>
@@ -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<KeyserverInfo>();
+}
+
+void SQLiteQueryExecutor::removeKeyservers(
+ const std::vector<std::string> &ids) const {
+ SQLiteQueryExecutor::getStorage().remove_all<KeyserverInfo>(
+ where(in(&KeyserverInfo::id, ids)));
+}
+
+std::vector<KeyserverInfo> SQLiteQueryExecutor::getAllKeyservers() const {
+ return SQLiteQueryExecutor::getStorage().get_all<KeyserverInfo>();
+}
+
std::vector<UserInfo> SQLiteQueryExecutor::getAllUsers() const {
return SQLiteQueryExecutor::getStorage().get_all<UserInfo>();
}
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 <string>
+
+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>("UserInfo")
.field("id", &UserInfo::id)
.field("userInfo", &UserInfo::user_info);
+ value_object<KeyserverInfo>("KeyserverInfo")
+ .field("id", &KeyserverInfo::id)
+ .field("keyserverInfo", &KeyserverInfo::keyserver_info);
value_object<WebThread>("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;b<Y.length;++b)void 0!==Y[b]&&++a;return a};e.get_first_emval=function(){for(var a=5;a<Y.length;++a)if(void 0!==Y[a])return Y[a];return null};
var Lc={a:function(a){return wc(a+24)+24},b:function(a,b,c){(new Oa(a)).Cb(b,c);Pa++;throw a;},Z:function(a,b){try{return a=y(a),N.chmod(a,b),0}catch(c){if("undefined"==typeof N||!(c instanceof N.La))throw c;return-c.Qa}},ca:function(a,b,c){try{b=y(b);b=P(a,b);if(c&-8)return-28;var d=N.Ta(b,{cb:!0}).node;if(!d)return-44;a="";c&4&&(a+="r");c&2&&(a+="w");c&1&&(a+="x");return a&&N.rb(d,a)?-2:0}catch(f){if("undefined"==typeof N||!(f instanceof N.La))throw f;return-f.Qa}},_:function(a,b){try{return N.fchmod(a,
-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}},e: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"==
+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<d)return-68;A(c,z,a,b);return d}catch(f){if("undefined"==
typeof N||!(f instanceof N.La))throw f;return-f.Qa}},L:function(a,b,c){try{var d=Q(a);d.tb||(d.tb=N.readdir(d.path));a=0;for(var f=N.ab(d,0,1),g=Math.floor(f/280);g<d.tb.length&&a+280<=c;){var k=d.tb[g];if("."===k){var h=d.node.id;var n=4}else if(".."===k)h=N.Ta(d.path,{parent:!0}).node.id,n=4;else{var q=N.jb(d.node,k);h=q.id;n=N.Ib(q.mode)?2:N.Xa(q.mode)?4:N.ub(q.mode)?10:8}J=[h>>>0,(G=h,1<=+Math.abs(G)?0<G?(Math.min(+Math.floor(G/4294967296),4294967295)|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<G?(Math.min(+Math.floor(G/4294967296),4294967295)|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>>>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<f;++h)q[h]=String.fromCharCode(z[g+h]);q=q.join("")}X(d);return q},toWireType:function(d,f){f instanceof ArrayBuffer&&(f=new Uint8Array(f));var g="string"==typeof f;g||f instanceof Uint8Array||f instanceof Uint8ClampedArray||f instanceof Int8Array||T("Cannot pass non-string to std::string");
var k=c&&g?ta(f):f.length;var h=wc(4+k+1),n=h+4;F[h>>2]=k;if(c&&g)A(f,z,n,k+1);else if(g)for(g=0;g<k;++g){var q=f.charCodeAt(g);255<q&&(X(n),T("String has UTF-16 code units that do not fit in 8 bits"));z[n+g]=q}else for(g=0;g<k;++g)z[n+g]=f[g];null!==d&&d.push(X,h);return h},argPackAdvance:8,readValueFromPointer:lb,hb:function(d){X(d)}})},o:function(a,b,c){c=S(c);if(2===b){var d=ic;var f=jc;var g=kc;var k=()=>va;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<a-1;++h)k+=(0!==h?", ":"")+"arg"+h,f.push("argType"+h),g.push(c[1+h]);var n="return function "+pb("methodCaller_"+b)+"(handle, name, destructors, args) {\n",q=0;for(h=0;h<a-1;++h)n+=" var arg"+h+" = argType"+h+".readValueFromPointer(args"+(q?"+"+q:"")+");\n",q+=c[h+1].argPackAdvance;n+=" var rv = handle[name]("+k+");\n";for(h=0;h<a-1;++h)c[h+1].deleteObject&&(n+=" argType"+h+".deleteObject(arg"+h+");\n");d.Cd||(n+=" return retType.toWireType(destructors, rv);\n");
f.push(n+"};\n");a=ac(f).apply(null,g);f=sc(a);return uc[b]=f},y:function(a,b){a=ec(a);b=ec(b);return Sb(a[b])},oa:function(a){4<a&&(Y[a].tc+=1)},na:function(){return Sb([])},ja:function(a){return Sb(qc(a))},ia:function(a){var b=ec(a);kb(b);dc(a)},l:function(a,b){a=oc(a,"_emval_take_value");a=a.readValueFromPointer(b);return Sb(a)},aa:function(a,b){a=new Date(1E3*ib(a));E[b>>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$@<O00001
literal 0
Hc$@<O00001
diff --git a/web/database/queries/keyservers-queries.test.js b/web/database/queries/keyservers-queries.test.js
new file mode 100644
--- /dev/null
+++ b/web/database/queries/keyservers-queries.test.js
@@ -0,0 +1,121 @@
+// @flow
+
+import {
+ convertKeyserverInfoToClientDBKeyserverInfo,
+ keyserverStoreOpsHandlers,
+} from 'lib/ops/keyserver-store-ops.js';
+import type { KeyserverInfo } from 'lib/types/keyserver-types.js';
+import { defaultConnectionInfo } from 'lib/types/socket-types.js';
+
+import { getDatabaseModule } from '../db-module.js';
+import type { EmscriptenModule } from '../types/module.js';
+import { type SQLiteQueryExecutor } from '../types/sqlite-query-executor.js';
+import { clearSensitiveData } from '../utils/db-utils.js';
+
+const FILE_PATH = 'test.sqlite';
+
+const TEST_KEYSERVER_1: KeyserverInfo = {
+ cookie: 'testCookie1',
+ updatesCurrentAsOf: 0,
+ urlPrefix: 'localhost',
+ connection: {
+ ...defaultConnectionInfo,
+ },
+ deviceToken: 'token',
+ lastCommunicatedPlatformDetails: null,
+};
+const TEST_KEYSERVER_2: KeyserverInfo = {
+ cookie: 'testCookie2',
+ updatesCurrentAsOf: 0,
+ urlPrefix: 'localhost',
+ connection: {
+ ...defaultConnectionInfo,
+ },
+ deviceToken: 'token',
+ lastCommunicatedPlatformDetails: null,
+};
+
+describe('Keyserver Store queries', () => {
+ 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<string>): void;
+ removeAllKeyservers(): void;
+ getAllKeyservers(): ClientDBKeyserverInfo[];
+
beginTransaction(): void;
commitTransaction(): void;
rollbackTransaction(): void;

File Metadata

Mime Type
text/plain
Expires
Sun, Nov 24, 12:22 PM (20 h, 48 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2575547
Default Alt Text
D10775.diff (18 KB)

Event Timeline