@vex-chat/libvex 0.27.1 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Storage.js CHANGED
@@ -1,47 +1,38 @@
1
- "use strict";
2
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
- return new (P || (P = Promise))(function (resolve, reject) {
5
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
- step((generator = generator.apply(thisArg, _arguments || [])).next());
9
- });
10
- };
11
- var __importDefault = (this && this.__importDefault) || function (mod) {
12
- return (mod && mod.__esModule) ? mod : { "default": mod };
13
- };
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.Storage = void 0;
16
- const sleep_1 = require("@extrahash/sleep");
17
- const crypto_1 = require("@vex-chat/crypto");
18
- const events_1 = require("events");
19
- const knex_1 = __importDefault(require("knex"));
20
- const parse_duration_1 = __importDefault(require("parse-duration"));
21
- const tweetnacl_1 = __importDefault(require("tweetnacl"));
22
- const createLogger_1 = require("./utils/createLogger");
23
- const sqlSessionToCrypto_1 = require("./utils/sqlSessionToCrypto");
1
+ import { sleep } from "@extrahash/sleep";
2
+ import { XKeyConvert, XUtils } from "@vex-chat/crypto";
3
+ import { EventEmitter } from "events";
4
+ import knex, {} from "knex";
5
+ import parseDuration from "parse-duration";
6
+ import nacl from "tweetnacl";
7
+ import winston from "winston";
8
+ import { createLogger } from "./utils/createLogger.js";
9
+ import { sqlSessionToCrypto } from "./utils/sqlSessionToCrypto.js";
24
10
  /**
25
11
  * The default IStorage() implementation, using knex and sqlite3 driver
26
12
  *
27
13
  * @hidden
28
14
  */
29
- class Storage extends events_1.EventEmitter {
15
+ export class Storage extends EventEmitter {
16
+ ready = false;
17
+ closing = false;
18
+ dbPath;
19
+ db;
20
+ log;
21
+ idKeys;
22
+ saveHistory;
30
23
  constructor(dbPath, SK, options) {
31
24
  super();
32
- this.ready = false;
33
- this.closing = false;
34
- this.log = createLogger_1.createLogger("db", (options === null || options === void 0 ? void 0 : options.dbLogLevel) || (options === null || options === void 0 ? void 0 : options.logLevel));
35
- const idKeys = crypto_1.XKeyConvert.convertKeyPair(tweetnacl_1.default.sign.keyPair.fromSecretKey(crypto_1.XUtils.decodeHex(SK)));
25
+ this.log = createLogger("db", options?.dbLogLevel || options?.logLevel);
26
+ const idKeys = XKeyConvert.convertKeyPair(nacl.sign.keyPair.fromSecretKey(XUtils.decodeHex(SK)));
36
27
  if (!idKeys) {
37
28
  throw new Error("Can't convert SK!");
38
29
  }
39
- this.saveHistory = (options === null || options === void 0 ? void 0 : options.saveHistory) || true;
30
+ this.saveHistory = options?.saveHistory || true;
40
31
  this.idKeys = idKeys;
41
32
  this.dbPath = dbPath;
42
33
  this.log.info("Opening database file at " + this.dbPath);
43
- this.db = knex_1.default({
44
- client: "sqlite3",
34
+ this.db = knex({
35
+ client: "better-sqlite3",
45
36
  connection: {
46
37
  filename: this.dbPath,
47
38
  },
@@ -49,461 +40,416 @@ class Storage extends events_1.EventEmitter {
49
40
  });
50
41
  this.init();
51
42
  }
52
- close() {
53
- return __awaiter(this, void 0, void 0, function* () {
54
- this.closing = true;
55
- this.log.info("Closing database.");
56
- yield this.db.destroy();
57
- });
43
+ async close() {
44
+ this.closing = true;
45
+ this.log.info("Closing database.");
46
+ await this.db.destroy();
58
47
  }
59
- saveMessage(message) {
60
- return __awaiter(this, void 0, void 0, function* () {
61
- if (!this.saveHistory) {
62
- return;
63
- }
64
- if (this.closing) {
65
- this.log.warn("Database is closing, saveMessage() will not complete.");
66
- return;
67
- }
68
- const copy = Object.assign({}, message);
69
- // encrypt plaintext with our idkey before it gets saved to disk
70
- copy.message = crypto_1.XUtils.encodeHex(tweetnacl_1.default.secretbox(crypto_1.XUtils.decodeUTF8(message.message), crypto_1.XUtils.decodeHex(message.nonce), this.idKeys.secretKey));
71
- try {
72
- yield this.db("messages").insert(copy);
73
- }
74
- catch (err) {
75
- if (err.errno !== 19) {
76
- throw err;
77
- }
78
- this.log.warn("Attempted to insert duplicate nonce into message table.");
48
+ async saveMessage(message) {
49
+ if (!this.saveHistory) {
50
+ return;
51
+ }
52
+ if (this.closing) {
53
+ this.log.warn("Database is closing, saveMessage() will not complete.");
54
+ return;
55
+ }
56
+ const copy = { ...message };
57
+ // encrypt plaintext with our idkey before it gets saved to disk
58
+ copy.message = XUtils.encodeHex(nacl.secretbox(XUtils.decodeUTF8(message.message), XUtils.decodeHex(message.nonce), this.idKeys.secretKey));
59
+ try {
60
+ await this.db("messages").insert(copy);
61
+ }
62
+ catch (err) {
63
+ if (err.errno !== 19) {
64
+ throw err;
79
65
  }
80
- });
66
+ this.log.warn("Attempted to insert duplicate nonce into message table.");
67
+ }
81
68
  }
82
- deleteMessage(mailID) {
83
- return __awaiter(this, void 0, void 0, function* () {
84
- if (this.closing) {
85
- this.log.warn("Database is closing, saveMessage() will not complete.");
86
- return;
87
- }
88
- yield this.db
89
- .from("messages")
90
- .where({ mailID })
91
- .del();
92
- });
69
+ async deleteMessage(mailID) {
70
+ if (this.closing) {
71
+ this.log.warn("Database is closing, saveMessage() will not complete.");
72
+ return;
73
+ }
74
+ await this.db
75
+ .from("messages")
76
+ .where({ mailID })
77
+ .del();
93
78
  }
94
- markSessionVerified(sessionID, status = true) {
95
- return __awaiter(this, void 0, void 0, function* () {
96
- if (this.closing) {
97
- this.log.warn("Database is closing, markSessionVerified() will not complete.");
98
- return;
99
- }
100
- yield this.db("sessions")
101
- .where({ sessionID })
102
- .update({ verified: status });
103
- });
79
+ async markSessionVerified(sessionID, status = true) {
80
+ if (this.closing) {
81
+ this.log.warn("Database is closing, markSessionVerified() will not complete.");
82
+ return;
83
+ }
84
+ await this.db("sessions")
85
+ .where({ sessionID })
86
+ .update({ verified: status });
104
87
  }
105
- getMessageHistory(userID) {
106
- return __awaiter(this, void 0, void 0, function* () {
107
- if (this.closing) {
108
- this.log.warn("Database is closing, getMessageHistory() will not complete.");
109
- return [];
110
- }
111
- const messages = yield this.db("messages")
112
- .select()
113
- .where({ direction: "incoming", authorID: userID, group: null })
114
- .orWhere({ direction: "outgoing", readerID: userID, group: null })
115
- .orderBy("timestamp", "desc");
116
- const fixedMessages = messages.reverse().map((message) => {
117
- // some cleanup because of how knex serializes the data
118
- message.timestamp = new Date(message.timestamp);
119
- // decrypt
120
- message.decrypted = Boolean(message.decrypted);
121
- if (message.decrypted) {
122
- const localDecrypt = tweetnacl_1.default.secretbox.open(crypto_1.XUtils.decodeHex(message.message), crypto_1.XUtils.decodeHex(message.nonce), this.idKeys.secretKey);
123
- if (localDecrypt) {
124
- message.message = crypto_1.XUtils.encodeUTF8(localDecrypt);
125
- }
126
- else {
127
- throw new Error("Couldn't decrypt messages on disk!");
128
- }
88
+ async getMessageHistory(userID) {
89
+ if (this.closing) {
90
+ this.log.warn("Database is closing, getMessageHistory() will not complete.");
91
+ return [];
92
+ }
93
+ const messages = await this.db("messages")
94
+ .select()
95
+ .where({ direction: "incoming", authorID: userID, group: null })
96
+ .orWhere({ direction: "outgoing", readerID: userID, group: null })
97
+ .orderBy("timestamp", "desc");
98
+ const fixedMessages = messages.reverse().map((message) => {
99
+ // some cleanup because of how knex serializes the data
100
+ message.timestamp = new Date(message.timestamp);
101
+ // decrypt
102
+ message.decrypted = Boolean(message.decrypted);
103
+ if (message.decrypted) {
104
+ const localDecrypt = nacl.secretbox.open(XUtils.decodeHex(message.message), XUtils.decodeHex(message.nonce), this.idKeys.secretKey);
105
+ if (localDecrypt) {
106
+ message.message = XUtils.encodeUTF8(localDecrypt);
129
107
  }
130
- return message;
131
- });
132
- this.log.debug("getMessageHistory() => " + JSON.stringify(fixedMessages, null, 4));
133
- return fixedMessages;
108
+ else {
109
+ throw new Error("Couldn't decrypt messages on disk!");
110
+ }
111
+ }
112
+ return message;
134
113
  });
114
+ this.log.debug("getMessageHistory() => " + JSON.stringify(fixedMessages, null, 4));
115
+ return fixedMessages;
135
116
  }
136
- getGroupHistory(channelID) {
137
- return __awaiter(this, void 0, void 0, function* () {
138
- if (this.closing) {
139
- this.log.warn("Database is closing, getGroupHistory() will not complete.");
140
- return [];
141
- }
142
- const messages = yield this.db("messages")
143
- .select()
144
- .where({ group: channelID })
145
- .orderBy("timestamp", "desc");
146
- const fixedMessages = messages.reverse().map((message) => {
147
- // some cleanup because of how knex serializes the data
148
- message.timestamp = new Date(message.timestamp);
149
- // decrypt
150
- message.decrypted = Boolean(message.decrypted);
151
- if (message.decrypted) {
152
- const localDecrypt = tweetnacl_1.default.secretbox.open(crypto_1.XUtils.decodeHex(message.message), crypto_1.XUtils.decodeHex(message.nonce), this.idKeys.secretKey);
153
- if (localDecrypt) {
154
- message.message = crypto_1.XUtils.encodeUTF8(localDecrypt);
155
- }
156
- else {
157
- throw new Error("Couldn't decrypt messages on disk!");
158
- }
117
+ async getGroupHistory(channelID) {
118
+ if (this.closing) {
119
+ this.log.warn("Database is closing, getGroupHistory() will not complete.");
120
+ return [];
121
+ }
122
+ const messages = await this.db("messages")
123
+ .select()
124
+ .where({ group: channelID })
125
+ .orderBy("timestamp", "desc");
126
+ const fixedMessages = messages.reverse().map((message) => {
127
+ // some cleanup because of how knex serializes the data
128
+ message.timestamp = new Date(message.timestamp);
129
+ // decrypt
130
+ message.decrypted = Boolean(message.decrypted);
131
+ if (message.decrypted) {
132
+ const localDecrypt = nacl.secretbox.open(XUtils.decodeHex(message.message), XUtils.decodeHex(message.nonce), this.idKeys.secretKey);
133
+ if (localDecrypt) {
134
+ message.message = XUtils.encodeUTF8(localDecrypt);
159
135
  }
160
- return message;
161
- });
162
- this.log.debug("getGroupHistory() => " + JSON.stringify(fixedMessages, null, 4));
163
- return fixedMessages;
136
+ else {
137
+ throw new Error("Couldn't decrypt messages on disk!");
138
+ }
139
+ }
140
+ return message;
164
141
  });
142
+ this.log.debug("getGroupHistory() => " + JSON.stringify(fixedMessages, null, 4));
143
+ return fixedMessages;
165
144
  }
166
- savePreKeys(preKeys, oneTime) {
167
- return __awaiter(this, void 0, void 0, function* () {
168
- const addedIndexes = [];
169
- yield this.untilReady();
170
- if (this.closing) {
171
- this.log.warn("Database is closing, savePreKeys() will not complete.");
172
- return [];
173
- }
174
- for (const preKey of preKeys) {
175
- const index = yield this.db(oneTime ? "oneTimeKeys" : "preKeys").insert({
176
- privateKey: crypto_1.XUtils.encodeHex(preKey.keyPair.secretKey),
177
- publicKey: crypto_1.XUtils.encodeHex(preKey.keyPair.publicKey),
178
- signature: crypto_1.XUtils.encodeHex(preKey.signature),
179
- });
180
- addedIndexes.push(index[0]);
181
- }
182
- const addedKeys = (yield this.db
183
- .from(oneTime ? "oneTimeKeys" : "preKeys")
184
- .select()
185
- .whereIn("index", addedIndexes)).map((key) => {
186
- delete key.privateKey;
187
- return key;
145
+ async savePreKeys(preKeys, oneTime) {
146
+ const addedIndexes = [];
147
+ await this.untilReady();
148
+ if (this.closing) {
149
+ this.log.warn("Database is closing, savePreKeys() will not complete.");
150
+ return [];
151
+ }
152
+ for (const preKey of preKeys) {
153
+ const index = await this.db(oneTime ? "oneTimeKeys" : "preKeys").insert({
154
+ privateKey: XUtils.encodeHex(preKey.keyPair.secretKey),
155
+ publicKey: XUtils.encodeHex(preKey.keyPair.publicKey),
156
+ signature: XUtils.encodeHex(preKey.signature),
188
157
  });
189
- this.log.silly("savePreKeys() => " + JSON.stringify(addedKeys, null, 4));
190
- return addedKeys;
158
+ addedIndexes.push(index[0]);
159
+ }
160
+ const addedKeys = (await this.db
161
+ .from(oneTime ? "oneTimeKeys" : "preKeys")
162
+ .select()
163
+ .whereIn("index", addedIndexes)).map((key) => {
164
+ delete key.privateKey;
165
+ return key;
191
166
  });
167
+ this.log.silly("savePreKeys() => " + JSON.stringify(addedKeys, null, 4));
168
+ return addedKeys;
192
169
  }
193
- getSessionByPublicKey(publicKey) {
194
- return __awaiter(this, void 0, void 0, function* () {
195
- if (this.closing) {
196
- this.log.warn("Database is closing, getGroupHistory() will not complete.");
197
- return null;
198
- }
199
- const str = crypto_1.XUtils.encodeHex(publicKey);
200
- const rows = yield this.db
201
- .from("sessions")
202
- .select()
203
- .where({ publicKey: str })
204
- .limit(1);
205
- if (rows.length === 0) {
206
- this.log.warn(`getSessionByPublicKey(${crypto_1.XUtils.encodeHex(publicKey)}) => ` +
207
- JSON.stringify(null, null, 4));
208
- return null;
209
- }
210
- const [session] = rows;
211
- const wsSession = sqlSessionToCrypto_1.sqlSessionToCrypto(session);
212
- this.log.debug("getSessionByPublicKey() => " + JSON.stringify(wsSession, null, 4));
213
- return wsSession;
214
- });
170
+ async getSessionByPublicKey(publicKey) {
171
+ if (this.closing) {
172
+ this.log.warn("Database is closing, getGroupHistory() will not complete.");
173
+ return null;
174
+ }
175
+ const str = XUtils.encodeHex(publicKey);
176
+ const rows = await this.db
177
+ .from("sessions")
178
+ .select()
179
+ .where({ publicKey: str })
180
+ .limit(1);
181
+ if (rows.length === 0) {
182
+ this.log.warn(`getSessionByPublicKey(${XUtils.encodeHex(publicKey)}) => ` +
183
+ JSON.stringify(null, null, 4));
184
+ return null;
185
+ }
186
+ const [session] = rows;
187
+ const wsSession = sqlSessionToCrypto(session);
188
+ this.log.debug("getSessionByPublicKey() => " + JSON.stringify(wsSession, null, 4));
189
+ return wsSession;
215
190
  }
216
- markSessionUsed(sessionID) {
217
- return __awaiter(this, void 0, void 0, function* () {
218
- if (this.closing) {
219
- this.log.warn("Database is closing, markSessionUsed() will not complete.");
220
- return;
221
- }
222
- yield this.db
223
- .from("sessions")
224
- .update({ lastUsed: new Date(Date.now()) })
225
- .where({ sessionID });
226
- });
191
+ async markSessionUsed(sessionID) {
192
+ if (this.closing) {
193
+ this.log.warn("Database is closing, markSessionUsed() will not complete.");
194
+ return;
195
+ }
196
+ await this.db
197
+ .from("sessions")
198
+ .update({ lastUsed: new Date(Date.now()) })
199
+ .where({ sessionID });
227
200
  }
228
- getAllSessions() {
229
- return __awaiter(this, void 0, void 0, function* () {
230
- if (this.closing) {
231
- this.log.warn("Database is closing, getAllSessions() will not complete.");
232
- return [];
233
- }
234
- const rows = yield this.db
235
- .from("sessions")
236
- .select()
237
- .orderBy("lastUsed", "desc");
238
- const fixedRows = rows.map((session) => {
239
- session.verified = Boolean(session.verified);
240
- return session;
241
- });
242
- this.log.debug("getAllSessions() => " + JSON.stringify(fixedRows, null, 4));
243
- return fixedRows;
201
+ async getAllSessions() {
202
+ if (this.closing) {
203
+ this.log.warn("Database is closing, getAllSessions() will not complete.");
204
+ return [];
205
+ }
206
+ const rows = await this.db
207
+ .from("sessions")
208
+ .select()
209
+ .orderBy("lastUsed", "desc");
210
+ const fixedRows = rows.map((session) => {
211
+ session.verified = Boolean(session.verified);
212
+ return session;
244
213
  });
214
+ this.log.debug("getAllSessions() => " + JSON.stringify(fixedRows, null, 4));
215
+ return fixedRows;
245
216
  }
246
- getSessionByDeviceID(deviceID) {
247
- return __awaiter(this, void 0, void 0, function* () {
248
- if (this.closing) {
249
- this.log.warn("Database is closing, getSessionByUserID() will not complete.");
250
- return null;
251
- }
252
- const rows = yield this.db
253
- .from("sessions")
254
- .select()
255
- .where({ deviceID })
256
- .limit(1)
257
- .orderBy("lastUsed", "desc");
258
- if (rows.length === 0) {
259
- this.log.debug("getSession() => " + JSON.stringify(null, null, 4));
260
- return null;
261
- }
262
- const [session] = rows;
263
- const wsSession = {
264
- sessionID: session.sessionID,
265
- userID: session.userID,
266
- mode: session.mode,
267
- SK: crypto_1.XUtils.decodeHex(session.SK),
268
- publicKey: crypto_1.XUtils.decodeHex(session.publicKey),
269
- lastUsed: session.lastUsed,
270
- fingerprint: crypto_1.XUtils.decodeHex(session.fingerprint),
271
- };
272
- this.log.debug("getSession() => " + JSON.stringify(wsSession, null, 4));
273
- return wsSession;
274
- });
217
+ async getSessionByDeviceID(deviceID) {
218
+ if (this.closing) {
219
+ this.log.warn("Database is closing, getSessionByUserID() will not complete.");
220
+ return null;
221
+ }
222
+ const rows = await this.db
223
+ .from("sessions")
224
+ .select()
225
+ .where({ deviceID })
226
+ .limit(1)
227
+ .orderBy("lastUsed", "desc");
228
+ if (rows.length === 0) {
229
+ this.log.debug("getSession() => " + JSON.stringify(null, null, 4));
230
+ return null;
231
+ }
232
+ const [session] = rows;
233
+ const wsSession = {
234
+ sessionID: session.sessionID,
235
+ userID: session.userID,
236
+ mode: session.mode,
237
+ SK: XUtils.decodeHex(session.SK),
238
+ publicKey: XUtils.decodeHex(session.publicKey),
239
+ lastUsed: session.lastUsed,
240
+ fingerprint: XUtils.decodeHex(session.fingerprint),
241
+ };
242
+ this.log.debug("getSession() => " + JSON.stringify(wsSession, null, 4));
243
+ return wsSession;
275
244
  }
276
- getPreKeys() {
277
- return __awaiter(this, void 0, void 0, function* () {
278
- yield this.untilReady();
279
- if (this.closing) {
280
- this.log.warn("Database is closing, getPreKeys() will not complete.");
281
- return null;
282
- }
283
- const rows = yield this.db
284
- .from("preKeys")
285
- .select();
286
- if (rows.length === 0) {
287
- this.log.debug("getPreKeys() => " + JSON.stringify(null, null, 4));
288
- return null;
289
- }
290
- const [preKeyInfo] = rows;
291
- const preKeys = {
292
- keyPair: tweetnacl_1.default.box.keyPair.fromSecretKey(crypto_1.XUtils.decodeHex(preKeyInfo.privateKey)),
293
- signature: crypto_1.XUtils.decodeHex(preKeyInfo.signature),
294
- };
295
- this.log.debug("getPreKeys() => " + JSON.stringify(preKeys, null, 4));
296
- return preKeys;
297
- });
245
+ async getPreKeys() {
246
+ await this.untilReady();
247
+ if (this.closing) {
248
+ this.log.warn("Database is closing, getPreKeys() will not complete.");
249
+ return null;
250
+ }
251
+ const rows = await this.db
252
+ .from("preKeys")
253
+ .select();
254
+ if (rows.length === 0) {
255
+ this.log.debug("getPreKeys() => " + JSON.stringify(null, null, 4));
256
+ return null;
257
+ }
258
+ const [preKeyInfo] = rows;
259
+ const preKeys = {
260
+ keyPair: nacl.box.keyPair.fromSecretKey(XUtils.decodeHex(preKeyInfo.privateKey)),
261
+ signature: XUtils.decodeHex(preKeyInfo.signature),
262
+ };
263
+ this.log.debug("getPreKeys() => " + JSON.stringify(preKeys, null, 4));
264
+ return preKeys;
298
265
  }
299
- getOneTimeKey(index) {
300
- return __awaiter(this, void 0, void 0, function* () {
301
- yield this.untilReady();
302
- if (this.closing) {
303
- this.log.warn("Database is closing, getOneTimeKey() will not complete.");
304
- return null;
305
- }
306
- const rows = yield this.db
307
- .from("oneTimeKeys")
308
- .select()
309
- .where({ index });
310
- if (rows.length === 0) {
311
- this.log.debug("getOneTimeKey() => " + JSON.stringify(null, null, 4));
312
- return null;
313
- }
314
- const [otkInfo] = rows;
315
- const otk = {
316
- keyPair: tweetnacl_1.default.box.keyPair.fromSecretKey(crypto_1.XUtils.decodeHex(otkInfo.privateKey)),
317
- signature: crypto_1.XUtils.decodeHex(otkInfo.signature),
318
- index: otkInfo.index,
319
- };
320
- this.log.debug("getOneTimeKey() => " + JSON.stringify(otk, null, 4));
321
- return otk;
322
- });
266
+ async getOneTimeKey(index) {
267
+ await this.untilReady();
268
+ if (this.closing) {
269
+ this.log.warn("Database is closing, getOneTimeKey() will not complete.");
270
+ return null;
271
+ }
272
+ const rows = await this.db
273
+ .from("oneTimeKeys")
274
+ .select()
275
+ .where({ index });
276
+ if (rows.length === 0) {
277
+ this.log.debug("getOneTimeKey() => " + JSON.stringify(null, null, 4));
278
+ return null;
279
+ }
280
+ const [otkInfo] = rows;
281
+ const otk = {
282
+ keyPair: nacl.box.keyPair.fromSecretKey(XUtils.decodeHex(otkInfo.privateKey)),
283
+ signature: XUtils.decodeHex(otkInfo.signature),
284
+ index: otkInfo.index,
285
+ };
286
+ this.log.debug("getOneTimeKey() => " + JSON.stringify(otk, null, 4));
287
+ return otk;
323
288
  }
324
- deleteOneTimeKey(index) {
325
- return __awaiter(this, void 0, void 0, function* () {
326
- if (this.closing) {
327
- this.log.warn("Database is closing, deleteOneTimeKey() will not complete.");
328
- return;
329
- }
330
- // delete the otk
331
- yield this.db
332
- .from("oneTimeKeys")
333
- .delete()
334
- .where({ index });
335
- });
289
+ async deleteOneTimeKey(index) {
290
+ if (this.closing) {
291
+ this.log.warn("Database is closing, deleteOneTimeKey() will not complete.");
292
+ return;
293
+ }
294
+ // delete the otk
295
+ await this.db
296
+ .from("oneTimeKeys")
297
+ .delete()
298
+ .where({ index });
336
299
  }
337
- saveSession(session) {
338
- return __awaiter(this, void 0, void 0, function* () {
339
- if (this.closing) {
340
- this.log.warn("Database is closing, deleteOneTimeKey() will not complete.");
300
+ async saveSession(session) {
301
+ if (this.closing) {
302
+ this.log.warn("Database is closing, deleteOneTimeKey() will not complete.");
303
+ return;
304
+ }
305
+ try {
306
+ await this.db("sessions").insert(session);
307
+ }
308
+ catch (err) {
309
+ if (err.errno === 19) {
310
+ this.log.warn("Attempted to insert duplicate SK");
341
311
  return;
342
312
  }
343
- try {
344
- yield this.db("sessions").insert(session);
345
- }
346
- catch (err) {
347
- if (err.errno === 19) {
348
- this.log.warn("Attempted to insert duplicate SK");
349
- return;
350
- }
351
- else {
352
- throw err;
353
- }
313
+ else {
314
+ throw err;
354
315
  }
355
- });
316
+ }
356
317
  }
357
- getDevice(deviceID) {
358
- return __awaiter(this, void 0, void 0, function* () {
359
- const rows = yield this.db
360
- .from("devices")
361
- .select()
362
- .where({ deviceID });
363
- if (rows.length === 0) {
364
- return null;
365
- }
366
- return rows[0];
367
- });
318
+ async getDevice(deviceID) {
319
+ const rows = await this.db
320
+ .from("devices")
321
+ .select()
322
+ .where({ deviceID });
323
+ if (rows.length === 0) {
324
+ return null;
325
+ }
326
+ return rows[0];
368
327
  }
369
- purgeHistory() {
370
- return __awaiter(this, void 0, void 0, function* () {
371
- yield this.db.from("messages").truncate();
372
- });
328
+ async purgeHistory() {
329
+ await this.db.from("messages").truncate();
373
330
  }
374
- purgeKeyData() {
375
- return __awaiter(this, void 0, void 0, function* () {
376
- yield this.db.from("sessions").truncate();
377
- yield this.db.from("oneTimeKeys").truncate();
378
- yield this.db.from("preKeys").truncate();
379
- yield this.db.from("messages").truncate();
380
- });
331
+ async purgeKeyData() {
332
+ await this.db.from("sessions").truncate();
333
+ await this.db.from("oneTimeKeys").truncate();
334
+ await this.db.from("preKeys").truncate();
335
+ await this.db.from("messages").truncate();
336
+ }
337
+ async deleteHistory(channelOrUserID, olderThan) {
338
+ if (!olderThan) {
339
+ await this.db
340
+ .from("messages")
341
+ .where({ group: channelOrUserID })
342
+ .orWhere({ group: null, authorID: channelOrUserID })
343
+ .orWhere({ group: null, readerID: channelOrUserID })
344
+ .delete();
345
+ }
346
+ else {
347
+ const duration = parseDuration(olderThan);
348
+ if (!duration) {
349
+ throw new Error("Bad duration. See parse-duration library for more details.");
350
+ }
351
+ console.log(duration);
352
+ const res = await this.db
353
+ .from("messages")
354
+ .where("time", "<", new Date(Date.now() - duration).toISOString());
355
+ console.log(res);
356
+ }
381
357
  }
382
- deleteHistory(channelOrUserID, olderThan) {
383
- return __awaiter(this, void 0, void 0, function* () {
384
- if (!olderThan) {
385
- yield this.db
386
- .from("messages")
387
- .where({ group: channelOrUserID })
388
- .orWhere({ group: null, authorID: channelOrUserID })
389
- .orWhere({ group: null, readerID: channelOrUserID })
390
- .delete();
358
+ async saveDevice(device) {
359
+ if (this.closing) {
360
+ this.log.warn("Database is closing, saveDevice() will not complete.");
361
+ return;
362
+ }
363
+ try {
364
+ await this.db("devices").insert(device);
365
+ }
366
+ catch (err) {
367
+ if (err.errno === 19) {
368
+ this.log.warn("Attempted to insert duplicate deviceID");
369
+ return;
391
370
  }
392
371
  else {
393
- const duration = parse_duration_1.default(olderThan);
394
- if (!duration) {
395
- throw new Error("Bad duration. See parse-duration library for more details.");
396
- }
397
- console.log(duration);
398
- const res = yield this.db
399
- .from("messages")
400
- .where("time", "<", new Date(Date.now() - duration).toISOString());
401
- console.log(res);
372
+ throw err;
402
373
  }
403
- });
374
+ }
404
375
  }
405
- saveDevice(device) {
406
- return __awaiter(this, void 0, void 0, function* () {
407
- if (this.closing) {
408
- this.log.warn("Database is closing, saveDevice() will not complete.");
409
- return;
376
+ async init() {
377
+ this.log.info("Initializing database tables.");
378
+ try {
379
+ if (!(await this.db.schema.hasTable("messages"))) {
380
+ await this.db.schema.createTable("messages", (table) => {
381
+ table.string("nonce").primary();
382
+ table.string("sender").index();
383
+ table.string("recipient").index();
384
+ table.string("group").index();
385
+ table.string("mailID");
386
+ table.string("message");
387
+ table.string("direction");
388
+ table.date("timestamp");
389
+ table.boolean("decrypted");
390
+ table.boolean("forward");
391
+ table.string("authorID");
392
+ table.string("readerID");
393
+ });
410
394
  }
411
- try {
412
- yield this.db("devices").insert(device);
395
+ if (!(await this.db.schema.hasTable("devices"))) {
396
+ await this.db.schema.createTable("devices", (table) => {
397
+ table.string("deviceID").primary();
398
+ table.string("owner").index();
399
+ table.string("signKey");
400
+ table.string("name");
401
+ table.string("lastLogin");
402
+ table.boolean("deleted");
403
+ });
413
404
  }
414
- catch (err) {
415
- if (err.errno === 19) {
416
- this.log.warn("Attempted to insert duplicate deviceID");
417
- return;
418
- }
419
- else {
420
- throw err;
421
- }
405
+ if (!(await this.db.schema.hasTable("sessions"))) {
406
+ await this.db.schema.createTable("sessions", (table) => {
407
+ table.string("sessionID").primary();
408
+ table.string("userID");
409
+ table.string("deviceID");
410
+ table.string("SK").unique();
411
+ table.string("publicKey");
412
+ table.string("fingerprint");
413
+ table.string("mode");
414
+ table.date("lastUsed");
415
+ table.boolean("verified");
416
+ });
422
417
  }
423
- });
424
- }
425
- init() {
426
- return __awaiter(this, void 0, void 0, function* () {
427
- this.log.info("Initializing database tables.");
428
- try {
429
- if (!(yield this.db.schema.hasTable("messages"))) {
430
- yield this.db.schema.createTable("messages", (table) => {
431
- table.string("nonce").primary();
432
- table.string("sender").index();
433
- table.string("recipient").index();
434
- table.string("group").index();
435
- table.string("mailID");
436
- table.string("message");
437
- table.string("direction");
438
- table.date("timestamp");
439
- table.boolean("decrypted");
440
- table.boolean("forward");
441
- table.string("authorID");
442
- table.string("readerID");
443
- });
444
- }
445
- if (!(yield this.db.schema.hasTable("devices"))) {
446
- yield this.db.schema.createTable("devices", (table) => {
447
- table.string("deviceID").primary();
448
- table.string("owner").index();
449
- table.string("signKey");
450
- table.string("name");
451
- table.string("lastLogin");
452
- table.boolean("deleted");
453
- });
454
- }
455
- if (!(yield this.db.schema.hasTable("sessions"))) {
456
- yield this.db.schema.createTable("sessions", (table) => {
457
- table.string("sessionID").primary();
458
- table.string("userID");
459
- table.string("deviceID");
460
- table.string("SK").unique();
461
- table.string("publicKey");
462
- table.string("fingerprint");
463
- table.string("mode");
464
- table.date("lastUsed");
465
- table.boolean("verified");
466
- });
467
- }
468
- if (!(yield this.db.schema.hasTable("preKeys"))) {
469
- yield this.db.schema.createTable("preKeys", (table) => {
470
- table.increments("index");
471
- table.string("keyID").unique();
472
- table.string("userID");
473
- table.string("deviceID");
474
- table.string("privateKey");
475
- table.string("publicKey");
476
- table.string("signature");
477
- });
478
- }
479
- if (!(yield this.db.schema.hasTable("oneTimeKeys"))) {
480
- yield this.db.schema.createTable("oneTimeKeys", (table) => {
481
- table.increments("index");
482
- table.string("keyID").unique();
483
- table.string("userID");
484
- table.string("deviceID");
485
- table.string("privateKey");
486
- table.string("publicKey");
487
- table.string("signature");
488
- });
489
- }
490
- this.ready = true;
491
- this.emit("ready");
418
+ if (!(await this.db.schema.hasTable("preKeys"))) {
419
+ await this.db.schema.createTable("preKeys", (table) => {
420
+ table.increments("index");
421
+ table.string("keyID").unique();
422
+ table.string("userID");
423
+ table.string("deviceID");
424
+ table.string("privateKey");
425
+ table.string("publicKey");
426
+ table.string("signature");
427
+ });
492
428
  }
493
- catch (err) {
494
- this.emit("error", err);
429
+ if (!(await this.db.schema.hasTable("oneTimeKeys"))) {
430
+ await this.db.schema.createTable("oneTimeKeys", (table) => {
431
+ table.increments("index");
432
+ table.string("keyID").unique();
433
+ table.string("userID");
434
+ table.string("deviceID");
435
+ table.string("privateKey");
436
+ table.string("publicKey");
437
+ table.string("signature");
438
+ });
495
439
  }
496
- });
440
+ this.ready = true;
441
+ this.emit("ready");
442
+ }
443
+ catch (err) {
444
+ this.emit("error", err);
445
+ }
497
446
  }
498
- untilReady() {
499
- return __awaiter(this, void 0, void 0, function* () {
500
- let timeout = 1;
501
- while (!this.ready) {
502
- yield sleep_1.sleep(timeout);
503
- timeout *= 2;
504
- }
505
- });
447
+ async untilReady() {
448
+ let timeout = 1;
449
+ while (!this.ready) {
450
+ await sleep(timeout);
451
+ timeout *= 2;
452
+ }
506
453
  }
507
454
  }
508
- exports.Storage = Storage;
509
455
  //# sourceMappingURL=Storage.js.map