@vex-chat/libvex 2.0.0 → 4.0.0
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/README.md +3 -2
- package/dist/Client.d.ts +83 -59
- package/dist/Client.d.ts.map +1 -1
- package/dist/Client.js +143 -272
- package/dist/Client.js.map +1 -1
- package/dist/Storage.d.ts +3 -3
- package/dist/codec.d.ts +4 -4
- package/dist/codec.d.ts.map +1 -1
- package/dist/codec.js +4 -4
- package/dist/codec.js.map +1 -1
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/keystore/node.d.ts +2 -1
- package/dist/keystore/node.d.ts.map +1 -1
- package/dist/keystore/node.js +9 -3
- package/dist/keystore/node.js.map +1 -1
- package/dist/preset/common.d.ts +1 -3
- package/dist/preset/common.d.ts.map +1 -1
- package/dist/preset/node.d.ts +1 -2
- package/dist/preset/node.d.ts.map +1 -1
- package/dist/preset/node.js +3 -7
- package/dist/preset/node.js.map +1 -1
- package/dist/preset/test.d.ts +0 -1
- package/dist/preset/test.d.ts.map +1 -1
- package/dist/preset/test.js +1 -15
- package/dist/preset/test.js.map +1 -1
- package/dist/storage/node.d.ts +1 -2
- package/dist/storage/node.d.ts.map +1 -1
- package/dist/storage/node.js +2 -8
- package/dist/storage/node.js.map +1 -1
- package/dist/storage/sqlite.d.ts +11 -3
- package/dist/storage/sqlite.d.ts.map +1 -1
- package/dist/storage/sqlite.js +36 -33
- package/dist/storage/sqlite.js.map +1 -1
- package/dist/transport/types.d.ts +0 -6
- package/dist/transport/types.d.ts.map +1 -1
- package/dist/types/crypto.d.ts +5 -2
- package/dist/types/crypto.d.ts.map +1 -1
- package/dist/types/crypto.js +2 -2
- package/dist/types/identity.d.ts +6 -1
- package/dist/types/identity.d.ts.map +1 -1
- package/dist/types/identity.js +1 -1
- package/package.json +20 -12
- package/src/Client.ts +206 -424
- package/src/Storage.ts +3 -3
- package/src/__tests__/codec.test.ts +26 -21
- package/src/__tests__/harness/platform-transports.ts +2 -15
- package/src/__tests__/harness/poison-node-imports.ts +0 -1
- package/src/__tests__/harness/shared-suite.ts +0 -20
- package/src/__tests__/platform-browser.test.ts +5 -10
- package/src/__tests__/platform-node.test.ts +1 -2
- package/src/codec.ts +4 -4
- package/src/index.ts +9 -2
- package/src/keystore/node.ts +14 -3
- package/src/preset/common.ts +1 -7
- package/src/preset/node.ts +3 -19
- package/src/preset/test.ts +1 -18
- package/src/storage/node.ts +2 -13
- package/src/storage/sqlite.ts +44 -65
- package/src/transport/types.ts +0 -7
- package/src/types/crypto.ts +5 -2
- package/src/types/identity.ts +6 -1
- package/dist/utils/createLogger.d.ts +0 -6
- package/dist/utils/createLogger.d.ts.map +0 -1
- package/dist/utils/createLogger.js +0 -27
- package/dist/utils/createLogger.js.map +0 -1
- package/src/utils/createLogger.ts +0 -37
package/src/storage/sqlite.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import type { Message } from "../index.js";
|
|
2
2
|
import type { Storage } from "../Storage.js";
|
|
3
|
-
import type { Logger } from "../transport/types.js";
|
|
4
3
|
import type {
|
|
5
4
|
PreKeysCrypto,
|
|
6
5
|
SessionCrypto,
|
|
@@ -29,6 +28,7 @@ import {
|
|
|
29
28
|
type KeyPair,
|
|
30
29
|
xBoxKeyPairFromSecret,
|
|
31
30
|
XKeyConvert,
|
|
31
|
+
xMakeNonce,
|
|
32
32
|
xSecretbox,
|
|
33
33
|
xSecretboxOpen,
|
|
34
34
|
xSignKeyPairFromSecret,
|
|
@@ -42,12 +42,10 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
42
42
|
private closing = false;
|
|
43
43
|
private readonly db: Kysely<ClientDatabase>;
|
|
44
44
|
private readonly idKeys: KeyPair;
|
|
45
|
-
private readonly log: Logger;
|
|
46
45
|
|
|
47
|
-
constructor(db: Kysely<ClientDatabase>, SK: string
|
|
46
|
+
constructor(db: Kysely<ClientDatabase>, SK: string) {
|
|
48
47
|
super();
|
|
49
48
|
this.db = db;
|
|
50
|
-
this.log = logger;
|
|
51
49
|
|
|
52
50
|
const idKeys = XKeyConvert.convertKeyPair(
|
|
53
51
|
xSignKeyPairFromSecret(XUtils.decodeHex(SK)),
|
|
@@ -62,7 +60,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
62
60
|
|
|
63
61
|
async close(): Promise<void> {
|
|
64
62
|
this.closing = true;
|
|
65
|
-
this.log.info("Closing database.");
|
|
66
63
|
await this.db.destroy();
|
|
67
64
|
}
|
|
68
65
|
|
|
@@ -89,9 +86,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
89
86
|
|
|
90
87
|
async deleteMessage(mailID: string): Promise<void> {
|
|
91
88
|
if (this.closing) {
|
|
92
|
-
this.log.warn(
|
|
93
|
-
"Database is closing, deleteMessage() will not complete.",
|
|
94
|
-
);
|
|
95
89
|
return;
|
|
96
90
|
}
|
|
97
91
|
await this.db
|
|
@@ -102,9 +96,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
102
96
|
|
|
103
97
|
async deleteOneTimeKey(index: number): Promise<void> {
|
|
104
98
|
if (this.closing) {
|
|
105
|
-
this.log.warn(
|
|
106
|
-
"Database is closing, deleteOneTimeKey() will not complete.",
|
|
107
|
-
);
|
|
108
99
|
return;
|
|
109
100
|
}
|
|
110
101
|
await this.db
|
|
@@ -115,9 +106,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
115
106
|
|
|
116
107
|
async getAllSessions(): Promise<SessionSQL[]> {
|
|
117
108
|
if (this.closing) {
|
|
118
|
-
this.log.warn(
|
|
119
|
-
"Database is closing, getAllSessions() will not complete.",
|
|
120
|
-
);
|
|
121
109
|
return [];
|
|
122
110
|
}
|
|
123
111
|
const rows = await this.db
|
|
@@ -145,9 +133,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
145
133
|
|
|
146
134
|
async getGroupHistory(channelID: string): Promise<Message[]> {
|
|
147
135
|
if (this.closing) {
|
|
148
|
-
this.log.warn(
|
|
149
|
-
"Database is closing, getGroupHistory() will not complete.",
|
|
150
|
-
);
|
|
151
136
|
return [];
|
|
152
137
|
}
|
|
153
138
|
|
|
@@ -163,9 +148,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
163
148
|
|
|
164
149
|
async getMessageHistory(userID: string): Promise<Message[]> {
|
|
165
150
|
if (this.closing) {
|
|
166
|
-
this.log.warn(
|
|
167
|
-
"Database is closing, getMessageHistory() will not complete.",
|
|
168
|
-
);
|
|
169
151
|
return [];
|
|
170
152
|
}
|
|
171
153
|
|
|
@@ -197,9 +179,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
197
179
|
async getOneTimeKey(index: number): Promise<null | PreKeysCrypto> {
|
|
198
180
|
await this.untilReady();
|
|
199
181
|
if (this.closing) {
|
|
200
|
-
this.log.warn(
|
|
201
|
-
"Database is closing, getOneTimeKey() will not complete.",
|
|
202
|
-
);
|
|
203
182
|
return null;
|
|
204
183
|
}
|
|
205
184
|
|
|
@@ -211,13 +190,12 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
211
190
|
|
|
212
191
|
const otkInfo = rows[0];
|
|
213
192
|
if (!otkInfo) {
|
|
214
|
-
this.log.debug("getOneTimeKey() => " + JSON.stringify(null));
|
|
215
193
|
return null;
|
|
216
194
|
}
|
|
217
195
|
return {
|
|
218
196
|
index: otkInfo.index,
|
|
219
197
|
keyPair: xBoxKeyPairFromSecret(
|
|
220
|
-
XUtils.decodeHex(otkInfo.privateKey),
|
|
198
|
+
XUtils.decodeHex(this.unsealHex(otkInfo.privateKey)),
|
|
221
199
|
),
|
|
222
200
|
signature: XUtils.decodeHex(otkInfo.signature),
|
|
223
201
|
};
|
|
@@ -226,9 +204,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
226
204
|
async getPreKeys(): Promise<null | PreKeysCrypto> {
|
|
227
205
|
await this.untilReady();
|
|
228
206
|
if (this.closing) {
|
|
229
|
-
this.log.warn(
|
|
230
|
-
"Database is closing, getPreKeys() will not complete.",
|
|
231
|
-
);
|
|
232
207
|
return null;
|
|
233
208
|
}
|
|
234
209
|
|
|
@@ -236,13 +211,12 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
236
211
|
|
|
237
212
|
const preKeyInfo = rows[0];
|
|
238
213
|
if (!preKeyInfo) {
|
|
239
|
-
this.log.debug("getPreKeys() => " + JSON.stringify(null));
|
|
240
214
|
return null;
|
|
241
215
|
}
|
|
242
216
|
return {
|
|
243
217
|
index: preKeyInfo.index,
|
|
244
218
|
keyPair: xBoxKeyPairFromSecret(
|
|
245
|
-
XUtils.decodeHex(preKeyInfo.privateKey),
|
|
219
|
+
XUtils.decodeHex(this.unsealHex(preKeyInfo.privateKey)),
|
|
246
220
|
),
|
|
247
221
|
signature: XUtils.decodeHex(preKeyInfo.signature),
|
|
248
222
|
};
|
|
@@ -252,9 +226,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
252
226
|
deviceID: string,
|
|
253
227
|
): Promise<null | SessionCrypto> {
|
|
254
228
|
if (this.closing) {
|
|
255
|
-
this.log.warn(
|
|
256
|
-
"Database is closing, getSessionByDeviceID() will not complete.",
|
|
257
|
-
);
|
|
258
229
|
return null;
|
|
259
230
|
}
|
|
260
231
|
const rows = await this.db
|
|
@@ -267,7 +238,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
267
238
|
|
|
268
239
|
const sessionRow = rows[0];
|
|
269
240
|
if (!sessionRow) {
|
|
270
|
-
this.log.debug("getSession() => " + JSON.stringify(null));
|
|
271
241
|
return null;
|
|
272
242
|
}
|
|
273
243
|
|
|
@@ -278,9 +248,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
278
248
|
publicKey: Uint8Array,
|
|
279
249
|
): Promise<null | SessionCrypto> {
|
|
280
250
|
if (this.closing) {
|
|
281
|
-
this.log.warn(
|
|
282
|
-
"Database is closing, getSessionByPublicKey() will not complete.",
|
|
283
|
-
);
|
|
284
251
|
return null;
|
|
285
252
|
}
|
|
286
253
|
const hex = XUtils.encodeHex(publicKey);
|
|
@@ -294,9 +261,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
294
261
|
|
|
295
262
|
const sessionRow = rows[0];
|
|
296
263
|
if (!sessionRow) {
|
|
297
|
-
this.log.warn(
|
|
298
|
-
`getSessionByPublicKey(${hex}) => ${JSON.stringify(null)}`,
|
|
299
|
-
);
|
|
300
264
|
return null;
|
|
301
265
|
}
|
|
302
266
|
|
|
@@ -304,7 +268,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
304
268
|
}
|
|
305
269
|
|
|
306
270
|
async init(): Promise<void> {
|
|
307
|
-
this.log.info("Initializing database tables.");
|
|
308
271
|
try {
|
|
309
272
|
await this.db.schema
|
|
310
273
|
.createTable("messages")
|
|
@@ -388,9 +351,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
388
351
|
|
|
389
352
|
async markSessionUsed(sessionID: string): Promise<void> {
|
|
390
353
|
if (this.closing) {
|
|
391
|
-
this.log.warn(
|
|
392
|
-
"Database is closing, markSessionUsed() will not complete.",
|
|
393
|
-
);
|
|
394
354
|
return;
|
|
395
355
|
}
|
|
396
356
|
await this.db
|
|
@@ -404,9 +364,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
404
364
|
|
|
405
365
|
async markSessionVerified(sessionID: string): Promise<void> {
|
|
406
366
|
if (this.closing) {
|
|
407
|
-
this.log.warn(
|
|
408
|
-
"Database is closing, markSessionVerified() will not complete.",
|
|
409
|
-
);
|
|
410
367
|
return;
|
|
411
368
|
}
|
|
412
369
|
await this.db
|
|
@@ -429,9 +386,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
429
386
|
|
|
430
387
|
async saveDevice(device: Device): Promise<void> {
|
|
431
388
|
if (this.closing) {
|
|
432
|
-
this.log.warn(
|
|
433
|
-
"Database is closing, saveDevice() will not complete.",
|
|
434
|
-
);
|
|
435
389
|
return;
|
|
436
390
|
}
|
|
437
391
|
try {
|
|
@@ -448,7 +402,7 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
448
402
|
.execute();
|
|
449
403
|
} catch (err: unknown) {
|
|
450
404
|
if (this.isDuplicateError(err)) {
|
|
451
|
-
|
|
405
|
+
// duplicate deviceID — ignore
|
|
452
406
|
} else {
|
|
453
407
|
throw err;
|
|
454
408
|
}
|
|
@@ -459,9 +413,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
459
413
|
|
|
460
414
|
async saveMessage(message: Message): Promise<void> {
|
|
461
415
|
if (this.closing) {
|
|
462
|
-
this.log.warn(
|
|
463
|
-
"Database is closing, saveMessage() will not complete.",
|
|
464
|
-
);
|
|
465
416
|
return;
|
|
466
417
|
}
|
|
467
418
|
|
|
@@ -494,7 +445,7 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
494
445
|
.execute();
|
|
495
446
|
} catch (err: unknown) {
|
|
496
447
|
if (this.isDuplicateError(err)) {
|
|
497
|
-
|
|
448
|
+
// duplicate nonce — ignore
|
|
498
449
|
} else {
|
|
499
450
|
throw err;
|
|
500
451
|
}
|
|
@@ -507,9 +458,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
507
458
|
): Promise<PreKeysSQL[]> {
|
|
508
459
|
await this.untilReady();
|
|
509
460
|
if (this.closing) {
|
|
510
|
-
this.log.warn(
|
|
511
|
-
"Database is closing, savePreKeys() will not complete.",
|
|
512
|
-
);
|
|
513
461
|
return [];
|
|
514
462
|
}
|
|
515
463
|
|
|
@@ -520,7 +468,9 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
520
468
|
const row = await this.db
|
|
521
469
|
.insertInto(table)
|
|
522
470
|
.values({
|
|
523
|
-
privateKey:
|
|
471
|
+
privateKey: this.sealHex(
|
|
472
|
+
XUtils.encodeHex(preKey.keyPair.secretKey),
|
|
473
|
+
),
|
|
524
474
|
publicKey: XUtils.encodeHex(preKey.keyPair.publicKey),
|
|
525
475
|
signature: XUtils.encodeHex(preKey.signature),
|
|
526
476
|
})
|
|
@@ -544,9 +494,6 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
544
494
|
|
|
545
495
|
async saveSession(session: SessionSQL): Promise<void> {
|
|
546
496
|
if (this.closing) {
|
|
547
|
-
this.log.warn(
|
|
548
|
-
"Database is closing, saveSession() will not complete.",
|
|
549
|
-
);
|
|
550
497
|
return;
|
|
551
498
|
}
|
|
552
499
|
try {
|
|
@@ -559,14 +506,14 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
559
506
|
mode: session.mode,
|
|
560
507
|
publicKey: session.publicKey,
|
|
561
508
|
sessionID: session.sessionID,
|
|
562
|
-
SK: session.SK,
|
|
509
|
+
SK: this.sealHex(session.SK),
|
|
563
510
|
userID: session.userID,
|
|
564
511
|
verified: session.verified ? 1 : 0,
|
|
565
512
|
})
|
|
566
513
|
.execute();
|
|
567
514
|
} catch (err: unknown) {
|
|
568
515
|
if (this.isDuplicateError(err)) {
|
|
569
|
-
|
|
516
|
+
// duplicate SK — ignore
|
|
570
517
|
} else {
|
|
571
518
|
throw err;
|
|
572
519
|
}
|
|
@@ -634,6 +581,23 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
634
581
|
return false;
|
|
635
582
|
}
|
|
636
583
|
|
|
584
|
+
/**
|
|
585
|
+
* Encrypt a hex-encoded secret for at-rest storage.
|
|
586
|
+
* Returns hex(nonce || ciphertext) where nonce is 24 random bytes.
|
|
587
|
+
*/
|
|
588
|
+
private sealHex(plainHex: string): string {
|
|
589
|
+
const nonce = xMakeNonce();
|
|
590
|
+
const ct = xSecretbox(
|
|
591
|
+
XUtils.decodeHex(plainHex),
|
|
592
|
+
nonce,
|
|
593
|
+
this.idKeys.secretKey,
|
|
594
|
+
);
|
|
595
|
+
const sealed = new Uint8Array(nonce.length + ct.length);
|
|
596
|
+
sealed.set(nonce);
|
|
597
|
+
sealed.set(ct, nonce.length);
|
|
598
|
+
return XUtils.encodeHex(sealed);
|
|
599
|
+
}
|
|
600
|
+
|
|
637
601
|
private sessionRowToSQL(row: SessionRow): SessionSQL {
|
|
638
602
|
return {
|
|
639
603
|
deviceID: row.deviceID,
|
|
@@ -642,7 +606,7 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
642
606
|
mode: row.mode === "initiator" ? "initiator" : "receiver",
|
|
643
607
|
publicKey: row.publicKey,
|
|
644
608
|
sessionID: row.sessionID,
|
|
645
|
-
SK: row.SK,
|
|
609
|
+
SK: this.unsealHex(row.SK),
|
|
646
610
|
userID: row.userID,
|
|
647
611
|
verified: row.verified !== 0,
|
|
648
612
|
};
|
|
@@ -660,6 +624,21 @@ export class SqliteStorage extends EventEmitter implements Storage {
|
|
|
660
624
|
};
|
|
661
625
|
}
|
|
662
626
|
|
|
627
|
+
/**
|
|
628
|
+
* Decrypt a value produced by sealHex().
|
|
629
|
+
* Expects hex(nonce || ciphertext), returns the original hex string.
|
|
630
|
+
*/
|
|
631
|
+
private unsealHex(sealed: string): string {
|
|
632
|
+
const bytes = XUtils.decodeHex(sealed);
|
|
633
|
+
const nonce = bytes.slice(0, 24);
|
|
634
|
+
const ct = bytes.slice(24);
|
|
635
|
+
const plain = xSecretboxOpen(ct, nonce, this.idKeys.secretKey);
|
|
636
|
+
if (!plain) {
|
|
637
|
+
throw new Error("Failed to decrypt sealed column value.");
|
|
638
|
+
}
|
|
639
|
+
return XUtils.encodeHex(plain);
|
|
640
|
+
}
|
|
641
|
+
|
|
663
642
|
private async untilReady(): Promise<void> {
|
|
664
643
|
if (this.ready) return;
|
|
665
644
|
return new Promise((resolve) => {
|
package/src/transport/types.ts
CHANGED
|
@@ -1,10 +1,3 @@
|
|
|
1
|
-
export interface Logger {
|
|
2
|
-
debug(message: string, ...args: unknown[]): void;
|
|
3
|
-
error(message: string, ...args: unknown[]): void;
|
|
4
|
-
info(message: string, ...args: unknown[]): void;
|
|
5
|
-
warn(message: string, ...args: unknown[]): void;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
1
|
export type WebSocketEvent = keyof WebSocketEventMap;
|
|
9
2
|
|
|
10
3
|
export interface WebSocketEventMap {
|
package/src/types/crypto.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SDK-internal crypto types. These were moved from
|
|
2
|
+
* SDK-internal crypto types. These were moved from `@vex-chat/types`
|
|
3
3
|
* because they are only used by the SDK, never by the server.
|
|
4
4
|
*
|
|
5
|
-
* The KeyPair shape matches tweetnacl's nacl.BoxKeyPair without
|
|
5
|
+
* The KeyPair shape matches tweetnacl's `nacl.BoxKeyPair` without
|
|
6
6
|
* importing from tweetnacl — future WASM migration only changes this file.
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
|
+
/** A NaCl box key pair (Curve25519 public + secret). */
|
|
9
10
|
export interface KeyPair {
|
|
10
11
|
publicKey: Uint8Array;
|
|
11
12
|
secretKey: Uint8Array;
|
|
@@ -16,12 +17,14 @@ export interface PreKeysCrypto extends UnsavedPreKey {
|
|
|
16
17
|
index: number;
|
|
17
18
|
}
|
|
18
19
|
|
|
20
|
+
/** In-memory representation of an encryption session (not yet persisted to SQL). */
|
|
19
21
|
export interface SessionCrypto {
|
|
20
22
|
fingerprint: Uint8Array;
|
|
21
23
|
lastUsed: string;
|
|
22
24
|
mode: "initiator" | "receiver";
|
|
23
25
|
publicKey: Uint8Array;
|
|
24
26
|
sessionID: string;
|
|
27
|
+
/** Shared secret key derived during X3DH. */
|
|
25
28
|
SK: Uint8Array;
|
|
26
29
|
userID: string;
|
|
27
30
|
}
|
package/src/types/identity.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* SDK credential storage types. Moved from
|
|
2
|
+
* SDK credential storage types. Moved from `@vex-chat/types`
|
|
3
3
|
* because only the SDK and app consumers use them.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
+
/**
|
|
7
|
+
* Persistent credential store used by apps to save/load login state
|
|
8
|
+
* (e.g. Keychain on macOS, SecureStorage on mobile).
|
|
9
|
+
*/
|
|
6
10
|
export interface KeyStore {
|
|
7
11
|
clear(username: string): Promise<void>;
|
|
8
12
|
load(username?: string): Promise<null | StoredCredentials>;
|
|
9
13
|
save(creds: StoredCredentials): Promise<void>;
|
|
10
14
|
}
|
|
11
15
|
|
|
16
|
+
/** Credentials persisted between sessions for auto-login. */
|
|
12
17
|
export interface StoredCredentials {
|
|
13
18
|
deviceID: string;
|
|
14
19
|
deviceKey: string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createLogger.d.ts","sourceRoot":"","sources":["../../src/utils/createLogger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B;;GAEG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,kBA+B9D"}
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import winston from "winston";
|
|
2
|
-
/**
|
|
3
|
-
* @ignore
|
|
4
|
-
*/
|
|
5
|
-
export function createLogger(logName, logLevel) {
|
|
6
|
-
const logger = winston.createLogger({
|
|
7
|
-
defaultMeta: { service: "vex-" + logName },
|
|
8
|
-
format: winston.format.combine(winston.format.timestamp({
|
|
9
|
-
format: "YYYY-MM-DD HH:mm:ss",
|
|
10
|
-
}), winston.format.errors({ stack: true }), winston.format.splat(), winston.format.json()),
|
|
11
|
-
level: logLevel || "error",
|
|
12
|
-
transports: [
|
|
13
|
-
new winston.transports.File({
|
|
14
|
-
filename: "vex:" + logName + ".log",
|
|
15
|
-
level: "error",
|
|
16
|
-
}),
|
|
17
|
-
],
|
|
18
|
-
});
|
|
19
|
-
// Also log to console outside production.
|
|
20
|
-
if (process.env["NODE_ENV"] !== "production") {
|
|
21
|
-
logger.add(new winston.transports.Console({
|
|
22
|
-
format: winston.format.combine(winston.format.colorize(), winston.format.simple()),
|
|
23
|
-
}));
|
|
24
|
-
}
|
|
25
|
-
return logger;
|
|
26
|
-
}
|
|
27
|
-
//# sourceMappingURL=createLogger.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"createLogger.js","sourceRoot":"","sources":["../../src/utils/createLogger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAC;AAE9B;;GAEG;AACH,MAAM,UAAU,YAAY,CAAC,OAAe,EAAE,QAAiB;IAC3D,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;QAChC,WAAW,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAAE;QAC1C,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC1B,OAAO,CAAC,MAAM,CAAC,SAAS,CAAC;YACrB,MAAM,EAAE,qBAAqB;SAChC,CAAC,EACF,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,EACtC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,EACtB,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CACxB;QACD,KAAK,EAAE,QAAQ,IAAI,OAAO;QAC1B,UAAU,EAAE;YACR,IAAI,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;gBACxB,QAAQ,EAAE,MAAM,GAAG,OAAO,GAAG,MAAM;gBACnC,KAAK,EAAE,OAAO;aACjB,CAAC;SACL;KACJ,CAAC,CAAC;IACH,0CAA0C;IAC1C,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,YAAY,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,CACN,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC;YAC3B,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,EACzB,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAC1B;SACJ,CAAC,CACL,CAAC;IACN,CAAC;IACD,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
import winston from "winston";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @ignore
|
|
5
|
-
*/
|
|
6
|
-
export function createLogger(logName: string, logLevel?: string) {
|
|
7
|
-
const logger = winston.createLogger({
|
|
8
|
-
defaultMeta: { service: "vex-" + logName },
|
|
9
|
-
format: winston.format.combine(
|
|
10
|
-
winston.format.timestamp({
|
|
11
|
-
format: "YYYY-MM-DD HH:mm:ss",
|
|
12
|
-
}),
|
|
13
|
-
winston.format.errors({ stack: true }),
|
|
14
|
-
winston.format.splat(),
|
|
15
|
-
winston.format.json(),
|
|
16
|
-
),
|
|
17
|
-
level: logLevel || "error",
|
|
18
|
-
transports: [
|
|
19
|
-
new winston.transports.File({
|
|
20
|
-
filename: "vex:" + logName + ".log",
|
|
21
|
-
level: "error",
|
|
22
|
-
}),
|
|
23
|
-
],
|
|
24
|
-
});
|
|
25
|
-
// Also log to console outside production.
|
|
26
|
-
if (process.env["NODE_ENV"] !== "production") {
|
|
27
|
-
logger.add(
|
|
28
|
-
new winston.transports.Console({
|
|
29
|
-
format: winston.format.combine(
|
|
30
|
-
winston.format.colorize(),
|
|
31
|
-
winston.format.simple(),
|
|
32
|
-
),
|
|
33
|
-
}),
|
|
34
|
-
);
|
|
35
|
-
}
|
|
36
|
-
return logger;
|
|
37
|
-
}
|