glow.ts 1.0.3 → 1.1.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.
Files changed (121) hide show
  1. package/README.md +6 -15
  2. package/dist/glow.cjs.js +4 -0
  3. package/dist/glow.cjs.js.map +1 -0
  4. package/dist/glow.es.js +993 -0
  5. package/dist/glow.es.js.map +1 -0
  6. package/dist/index.d.ts +544 -0
  7. package/package.json +34 -26
  8. package/dist/cjs2/config.js +0 -18
  9. package/dist/cjs2/config.js.map +0 -1
  10. package/dist/cjs2/crypto-storage/crypto-storage.js +0 -118
  11. package/dist/cjs2/crypto-storage/crypto-storage.js.map +0 -1
  12. package/dist/cjs2/crypto-storage/in-memory-storage.js +0 -36
  13. package/dist/cjs2/crypto-storage/in-memory-storage.js.map +0 -1
  14. package/dist/cjs2/crypto-storage/local-storage.driver.js +0 -36
  15. package/dist/cjs2/crypto-storage/local-storage.driver.js.map +0 -1
  16. package/dist/cjs2/crypto-storage/storage-driver.interface.js +0 -3
  17. package/dist/cjs2/crypto-storage/storage-driver.interface.js.map +0 -1
  18. package/dist/cjs2/index.js +0 -28
  19. package/dist/cjs2/index.js.map +0 -1
  20. package/dist/cjs2/keyring/keyring.js +0 -151
  21. package/dist/cjs2/keyring/keyring.js.map +0 -1
  22. package/dist/cjs2/keys/keys.js +0 -40
  23. package/dist/cjs2/keys/keys.js.map +0 -1
  24. package/dist/cjs2/mailbox/mailbox.js +0 -352
  25. package/dist/cjs2/mailbox/mailbox.js.map +0 -1
  26. package/dist/cjs2/nacl/encryption.helper.js +0 -101
  27. package/dist/cjs2/nacl/encryption.helper.js.map +0 -1
  28. package/dist/cjs2/nacl/js-nacl-driver.js +0 -110
  29. package/dist/cjs2/nacl/js-nacl-driver.js.map +0 -1
  30. package/dist/cjs2/nacl/keypair.interface.js +0 -3
  31. package/dist/cjs2/nacl/keypair.interface.js.map +0 -1
  32. package/dist/cjs2/nacl/nacl-driver.interface.js +0 -3
  33. package/dist/cjs2/nacl/nacl-driver.interface.js.map +0 -1
  34. package/dist/cjs2/nacl/nacl.js +0 -29
  35. package/dist/cjs2/nacl/nacl.js.map +0 -1
  36. package/dist/cjs2/relay/network-error.js +0 -12
  37. package/dist/cjs2/relay/network-error.js.map +0 -1
  38. package/dist/cjs2/relay/relay-factory.js +0 -22
  39. package/dist/cjs2/relay/relay-factory.js.map +0 -1
  40. package/dist/cjs2/relay/relay.js +0 -300
  41. package/dist/cjs2/relay/relay.js.map +0 -1
  42. package/dist/cjs2/utils/utils.js +0 -39
  43. package/dist/cjs2/utils/utils.js.map +0 -1
  44. package/dist/cjs2/zax.interface.js +0 -46
  45. package/dist/cjs2/zax.interface.js.map +0 -1
  46. package/dist/esm/config.js +0 -15
  47. package/dist/esm/config.js.map +0 -1
  48. package/dist/esm/crypto-storage/crypto-storage.js +0 -114
  49. package/dist/esm/crypto-storage/crypto-storage.js.map +0 -1
  50. package/dist/esm/crypto-storage/in-memory-storage.js +0 -32
  51. package/dist/esm/crypto-storage/in-memory-storage.js.map +0 -1
  52. package/dist/esm/crypto-storage/local-storage.driver.js +0 -32
  53. package/dist/esm/crypto-storage/local-storage.driver.js.map +0 -1
  54. package/dist/esm/crypto-storage/storage-driver.interface.js +0 -2
  55. package/dist/esm/crypto-storage/storage-driver.interface.js.map +0 -1
  56. package/dist/esm/index.js +0 -14
  57. package/dist/esm/index.js.map +0 -1
  58. package/dist/esm/keyring/keyring.js +0 -147
  59. package/dist/esm/keyring/keyring.js.map +0 -1
  60. package/dist/esm/keys/keys.js +0 -36
  61. package/dist/esm/keys/keys.js.map +0 -1
  62. package/dist/esm/mailbox/mailbox.js +0 -348
  63. package/dist/esm/mailbox/mailbox.js.map +0 -1
  64. package/dist/esm/nacl/encryption.helper.js +0 -97
  65. package/dist/esm/nacl/encryption.helper.js.map +0 -1
  66. package/dist/esm/nacl/js-nacl-driver.js +0 -106
  67. package/dist/esm/nacl/js-nacl-driver.js.map +0 -1
  68. package/dist/esm/nacl/keypair.interface.js +0 -2
  69. package/dist/esm/nacl/keypair.interface.js.map +0 -1
  70. package/dist/esm/nacl/nacl-driver.interface.js +0 -2
  71. package/dist/esm/nacl/nacl-driver.interface.js.map +0 -1
  72. package/dist/esm/nacl/nacl.js +0 -25
  73. package/dist/esm/nacl/nacl.js.map +0 -1
  74. package/dist/esm/relay/network-error.js +0 -8
  75. package/dist/esm/relay/network-error.js.map +0 -1
  76. package/dist/esm/relay/relay-factory.js +0 -18
  77. package/dist/esm/relay/relay-factory.js.map +0 -1
  78. package/dist/esm/relay/relay.js +0 -293
  79. package/dist/esm/relay/relay.js.map +0 -1
  80. package/dist/esm/utils/utils.js +0 -35
  81. package/dist/esm/utils/utils.js.map +0 -1
  82. package/dist/esm/zax.interface.js +0 -43
  83. package/dist/esm/zax.interface.js.map +0 -1
  84. package/dist/types/config.d.ts +0 -10
  85. package/dist/types/config.d.ts.map +0 -1
  86. package/dist/types/crypto-storage/crypto-storage.d.ts +0 -20
  87. package/dist/types/crypto-storage/crypto-storage.d.ts.map +0 -1
  88. package/dist/types/crypto-storage/in-memory-storage.d.ts +0 -17
  89. package/dist/types/crypto-storage/in-memory-storage.d.ts.map +0 -1
  90. package/dist/types/crypto-storage/local-storage.driver.d.ts +0 -15
  91. package/dist/types/crypto-storage/local-storage.driver.d.ts.map +0 -1
  92. package/dist/types/crypto-storage/storage-driver.interface.d.ts +0 -11
  93. package/dist/types/crypto-storage/storage-driver.interface.d.ts.map +0 -1
  94. package/dist/types/index.d.ts +0 -16
  95. package/dist/types/index.d.ts.map +0 -1
  96. package/dist/types/keyring/keyring.d.ts +0 -43
  97. package/dist/types/keyring/keyring.d.ts.map +0 -1
  98. package/dist/types/keys/keys.d.ts +0 -16
  99. package/dist/types/keys/keys.d.ts.map +0 -1
  100. package/dist/types/mailbox/mailbox.d.ts +0 -148
  101. package/dist/types/mailbox/mailbox.d.ts.map +0 -1
  102. package/dist/types/nacl/encryption.helper.d.ts +0 -37
  103. package/dist/types/nacl/encryption.helper.d.ts.map +0 -1
  104. package/dist/types/nacl/js-nacl-driver.d.ts +0 -39
  105. package/dist/types/nacl/js-nacl-driver.d.ts.map +0 -1
  106. package/dist/types/nacl/keypair.interface.d.ts +0 -5
  107. package/dist/types/nacl/keypair.interface.d.ts.map +0 -1
  108. package/dist/types/nacl/nacl-driver.interface.d.ts +0 -28
  109. package/dist/types/nacl/nacl-driver.interface.d.ts.map +0 -1
  110. package/dist/types/nacl/nacl.d.ts +0 -13
  111. package/dist/types/nacl/nacl.d.ts.map +0 -1
  112. package/dist/types/relay/network-error.d.ts +0 -6
  113. package/dist/types/relay/network-error.d.ts.map +0 -1
  114. package/dist/types/relay/relay-factory.d.ts +0 -10
  115. package/dist/types/relay/relay-factory.d.ts.map +0 -1
  116. package/dist/types/relay/relay.d.ts +0 -88
  117. package/dist/types/relay/relay.d.ts.map +0 -1
  118. package/dist/types/utils/utils.d.ts +0 -9
  119. package/dist/types/utils/utils.d.ts.map +0 -1
  120. package/dist/types/zax.interface.d.ts +0 -101
  121. package/dist/types/zax.interface.d.ts.map +0 -1
@@ -0,0 +1,544 @@
1
+ declare type Base64 = string;
2
+
3
+ export declare class CryptoStorage {
4
+ private static storageDriver;
5
+ private driver?;
6
+ private id?;
7
+ private storageKey?;
8
+ private nacl;
9
+ private constructor();
10
+ static new(id: string): Promise<CryptoStorage>;
11
+ static getStorageDriver(): StorageDriver;
12
+ static setDefaultStorageDriver(): boolean;
13
+ static setStorageDriver(driver: StorageDriver): boolean;
14
+ save(tag: string, data: unknown): Promise<boolean>;
15
+ get<T>(tag: string): Promise<T | null>;
16
+ remove(tag: string): Promise<boolean>;
17
+ selfDestruct(): Promise<void>;
18
+ private addPrefix;
19
+ private addNonceTag;
20
+ }
21
+
22
+ declare interface DeleteFileResponse {
23
+ status: 'OK' | 'NOT_FOUND';
24
+ }
25
+
26
+ declare interface EncryptedMessage {
27
+ nonce: string;
28
+ ctext: string;
29
+ }
30
+
31
+ export declare interface FileStatusResponse {
32
+ status: 'COMPLETE' | 'UPLOADING' | 'START' | 'NOT_FOUND';
33
+ total_chunks: number;
34
+ file_size: number;
35
+ bytes_stored: number;
36
+ }
37
+
38
+ declare interface FileUploadMetadata {
39
+ name: string;
40
+ orig_size: number;
41
+ md5?: string;
42
+ created?: number;
43
+ modified?: number;
44
+ attrs?: string;
45
+ skey?: Base64;
46
+ }
47
+
48
+ export declare class GlowNetworkError extends Error {
49
+ status: number | undefined;
50
+ readonly name = "GlowNetworkError";
51
+ constructor(status: number | undefined);
52
+ }
53
+
54
+ /**
55
+ * temporary created in-memory storage for testing purposes
56
+ */
57
+ export declare class InMemoryStorage implements StorageDriver {
58
+ private storage;
59
+ get(key: string): Promise<string | null>;
60
+ getMultiple(keys: string[]): Promise<(string | null)[]>;
61
+ set<T extends string | null>(key: string, value: T): Promise<void>;
62
+ setMultiple<T extends string | null>(values: {
63
+ [key: string]: T;
64
+ }): Promise<void>;
65
+ remove(key: string): Promise<void>;
66
+ removeMultiple(keys: string[]): Promise<void>;
67
+ reset(): void;
68
+ }
69
+
70
+ /**
71
+ * Implementation based on TweetNaCl.js: {@link https://github.com/dchest/tweetnacl-js}.
72
+ * SHA256 is implemented using Web Crypto API (SubtleCrypto).
73
+ *
74
+ * All the methods of this class are actually synchronous, but they are defined
75
+ * as async to conform to the NaClDriver interface, which may have other implementations.
76
+ */
77
+ export declare class JsNaClDriver implements NaClDriver {
78
+ crypto_secretbox_KEYBYTES: number;
79
+ crypto_secretbox_random_nonce(): Promise<Uint8Array>;
80
+ crypto_secretbox(message: Uint8Array, nonce: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
81
+ crypto_secretbox_open(box: Uint8Array, nonce: Uint8Array, key: Uint8Array): Promise<Uint8Array | null>;
82
+ crypto_box_NONCEBYTES: number;
83
+ crypto_box(message: Uint8Array, nonce: Uint8Array, pk: Uint8Array, sk: Uint8Array): Promise<Uint8Array>;
84
+ crypto_box_open(cipher: Uint8Array, nonce: Uint8Array, pk: Uint8Array, sk: Uint8Array): Promise<Uint8Array | null>;
85
+ crypto_box_random_nonce(): Promise<Uint8Array>;
86
+ crypto_box_keypair(): Promise<Keypair>;
87
+ crypto_box_keypair_from_raw_sk(key: Uint8Array): Promise<Keypair>;
88
+ crypto_box_keypair_from_seed(seed: Uint8Array): Promise<Keypair>;
89
+ crypto_hash_sha256(data: Uint8Array): Promise<Uint8Array>;
90
+ random_bytes(size: number): Promise<Uint8Array>;
91
+ encode_latin1(data: string): Promise<Uint8Array>;
92
+ decode_latin1(data: Uint8Array): Promise<string>;
93
+ encode_utf8(data: string): Promise<Uint8Array>;
94
+ decode_utf8(data: Uint8Array): Promise<string>;
95
+ to_hex(data: Uint8Array): Promise<string>;
96
+ from_hex(data: string): Promise<Uint8Array>;
97
+ /**
98
+ * h2(m) = sha256(sha256(64x0 + m))
99
+ * Zero out initial sha256 block, and double hash 0-padded message
100
+ * http://cs.nyu.edu/~dodis/ps/h-of-h.pdf
101
+ */
102
+ h2(data: string | Uint8Array): Promise<Uint8Array>;
103
+ }
104
+
105
+ export declare interface Keypair {
106
+ boxPk: Uint8Array;
107
+ boxSk: Uint8Array;
108
+ }
109
+
110
+ declare interface KeyRecord {
111
+ pk: Base64;
112
+ hpk: Base64;
113
+ }
114
+
115
+ export declare class KeyRing {
116
+ static readonly commKeyTag = "comm_key";
117
+ static readonly guestRegistryTag = "guest_registry";
118
+ private commKey;
119
+ private storage;
120
+ private guestKeys;
121
+ private nacl;
122
+ private constructor();
123
+ static new(id: string): Promise<KeyRing>;
124
+ static fromBackup(id: string, backupString: string): Promise<KeyRing>;
125
+ getNumberOfGuests(): number;
126
+ get guests(): Map<string, KeyRecord>;
127
+ /**
128
+ * Returns public identity, which is the default communication key.
129
+ * Correspondents can know it, whereas Relays do not need it (other than
130
+ * temporarily for internal use during the ownership proof)
131
+ */
132
+ getPubCommKey(): string;
133
+ getPrivateCommKey(): string;
134
+ /**
135
+ * Returns HPK (hash of the public key) of the mailbox. This is what Zax relays
136
+ * uses as the universal address of the mailbox
137
+ */
138
+ getHpk(): Promise<Base64>;
139
+ getTagByHpk(hpk: string): string | null;
140
+ getGuestKey(guestTag: string): Base64 | null;
141
+ backup(): Promise<string>;
142
+ setCommFromSeed(seed: Uint8Array): Promise<void>;
143
+ setCommFromSecKey(rawSecretKey: Uint8Array): Promise<void>;
144
+ addGuest(guestTag: string, publicKey: Base64): Promise<string>;
145
+ removeGuest(guestTag: string): Promise<boolean>;
146
+ private loadGuestKeys;
147
+ private saveGuests;
148
+ private static getCommKeyOrCreate;
149
+ selfDestruct(): Promise<void>;
150
+ }
151
+
152
+ /**
153
+ * A simple wrapper around a public/private keys pair.
154
+ * Stores keys in base64 format.
155
+ */
156
+ export declare class Keys {
157
+ keys: string | Keypair;
158
+ private keyPair;
159
+ constructor(keys: string | Keypair);
160
+ static isEqual(keys1: Keys, keys2: Keys): boolean;
161
+ toString(): string;
162
+ get publicKey(): Base64;
163
+ get privateKey(): Base64;
164
+ }
165
+
166
+ export declare class LocalStorageDriver implements StorageDriver {
167
+ private rootTag;
168
+ constructor(root?: string);
169
+ get(key: string): Promise<string | null>;
170
+ getMultiple(keys: string[]): Promise<(string | null)[]>;
171
+ set(key: string, value: string | null): Promise<void>;
172
+ setMultiple(values: {
173
+ [key: string]: string | null;
174
+ }): Promise<void>;
175
+ remove(key: string): Promise<void>;
176
+ removeMultiple(keys: string[]): Promise<void>;
177
+ private tag;
178
+ }
179
+
180
+ /**
181
+ * Mailbox class represents a wrapper around a Keyring that allows to exchange
182
+ * encrypted messages with other Mailboxes via a relay
183
+ */
184
+ export declare class Mailbox {
185
+ keyRing: KeyRing;
186
+ identity: string;
187
+ /**
188
+ * each mailbox use it's own relays for connection
189
+ * this gives possibility to connect different mailboxes to same server simultaneously
190
+ * because they will use different session keys, tokens, server pub keys
191
+ */
192
+ private relayFactory;
193
+ private relayConnectionMutexes;
194
+ private nacl;
195
+ private constructor();
196
+ static new(identity: string): Promise<Mailbox>;
197
+ /**
198
+ * Create a Mailbox where the secret identity key is derived from a well-known seed
199
+ */
200
+ static fromSeed(id: string, seed: Uint8Array | string): Promise<Mailbox>;
201
+ /**
202
+ * Create a Mailbox from the known secret identity key
203
+ */
204
+ static fromSecKey(id: string, rawSecretKey: Uint8Array | Base64): Promise<Mailbox>;
205
+ /**
206
+ * Create a Mailbox from the backup string
207
+ */
208
+ static fromBackup(identity: string, backup: string): Promise<Mailbox>;
209
+ /**
210
+ * Sends a free-form object to a guest we already have in our keyring. Set `encrypt` to `false` to
211
+ * send a plaintext message. Returns a token that can be used with `messageStatus` command to check
212
+ * the status of the message
213
+ */
214
+ upload(url: string, guestKey: string, message: string, encrypt?: boolean): Promise<Base64>;
215
+ /**
216
+ * Downloads all messages from a relay, decrypts them with a relay key,
217
+ * and then parses each message to find out if it's a text message, file message,
218
+ * or if it can't be decrypted because HPK is missing in the keyring.
219
+ * Returns an array of mixed messages
220
+ */
221
+ download(url: string): Promise<ZaxParsedMessage[]>;
222
+ /**
223
+ * Marks a raw Zax message as one that can't be decrypted,
224
+ * because sender's HPK is not found in the keyring
225
+ */
226
+ private parsePlainMessage;
227
+ /**
228
+ * Decrypts a message that represents uploaded file metadata
229
+ */
230
+ private parseFileMessage;
231
+ /**
232
+ * Attempts to decrypt a regular encrypted Zax message. Returns plain message if it was sent encrypted
233
+ */
234
+ private parseTextMessage;
235
+ /**
236
+ * Returns the number of messages in the mailbox on a given relay
237
+ */
238
+ count(url: string): Promise<number>;
239
+ /**
240
+ * Deletes messages from a relay given a list of base64 message nonces,
241
+ * and returns the number of remaining messages
242
+ */
243
+ delete(url: string, nonceList: Base64[]): Promise<number>;
244
+ /**
245
+ * Gets the status of a previously sent Zax message by a storage token.
246
+ * Returns "time to live" in seconds or a negative value if it's not applicable.
247
+ * See `MessageStatusResponse` values for reference
248
+ */
249
+ messageStatus(url: string, storageToken: Base64): Promise<MessageStatusResponse | number>;
250
+ /**
251
+ * Asks Zax to start a new upload session, and returns a unique file identifier
252
+ * required to upload file chunks.
253
+ */
254
+ startFileUpload(url: string, guest: string, rawMetadata: FileUploadMetadata): Promise<StartFileUploadResponse>;
255
+ /**
256
+ * Encrypts the file chunk symmetrically and transfers it to a relay
257
+ */
258
+ uploadFileChunk(url: string, uploadID: string, chunk: Uint8Array, part: number, totalParts: number, skey: Uint8Array): Promise<UploadFileChunkResponse>;
259
+ /**
260
+ * Returns the status of a file upload by its relay-specific uploadID. Uploader can call it
261
+ * to verify the correct transfer, and downloader can check if the file exists and retrieve
262
+ * the number of chunks
263
+ */
264
+ getFileStatus(url: string, uploadID: string): Promise<FileStatusResponse>;
265
+ /**
266
+ * Fetches the file metadata by uploadID, which was declared by the uploader
267
+ */
268
+ getFileMetadata(url: string, uploadID: string): Promise<FileUploadMetadata>;
269
+ /**
270
+ * Downloads a binary chunk of a file from a relay by a given uploadID. The total number of chunks
271
+ * can be retrieved via a `getFileStatus` request
272
+ */
273
+ downloadFileChunk(url: string, uploadID: string, part: number, skey: Uint8Array | Base64): Promise<Uint8Array | null>;
274
+ /**
275
+ * Deletes a file from the relay (or all chunks uploaded so far, if the upload was not completed).
276
+ * Can be called by either the sender or recipient
277
+ */
278
+ deleteFile(url: string, uploadID: string): Promise<DeleteFileResponse>;
279
+ /**
280
+ * Establishes a session, exchanges temp keys and proves our ownership of this
281
+ * Mailbox to this specific relay. This is the first function to start
282
+ * communications with any relay. Returns the number of messages in the mailbox
283
+ */
284
+ connectToRelay(url: string): Promise<number>;
285
+ clearSession(url: string): void;
286
+ private encryptSignature;
287
+ /**
288
+ * Gets a singleton Relay instance, and reconnects to a relay if a previous token has expired
289
+ */
290
+ private prepareRelay;
291
+ /**
292
+ * Encrypts the payload of the command and sends it to a relay
293
+ */
294
+ private runRelayCommand;
295
+ /**
296
+ * Parses relay's response to a command, for those commands that expect an encrypted message in return.
297
+ * Two lines of POST response will be nonce and ctext
298
+ */
299
+ private decryptResponse;
300
+ /**
301
+ * Encodes `message` to the guest key of a guest already
302
+ * added to the keyring
303
+ */
304
+ encodeMessage(guest: string, message: string): Promise<EncryptedMessage>;
305
+ /**
306
+ * Decodes a ciphertext from a guest key already in our keyring with this nonce
307
+ * @returns null if failed to decode
308
+ */
309
+ decodeMessage(guest: string, nonce: Base64, ctext: Base64): Promise<string | null>;
310
+ /**
311
+ * Wrapper around `keyring.getGuestKey` that handles unknown guests
312
+ */
313
+ private getGuestKey;
314
+ /**
315
+ * Deletes a Mailbox and all its data from local CryptoStorage. This is a very
316
+ * destructive operation, use with caution - it will delete the Mailbox
317
+ * keyring along with all stored public keys. To restore that information, you
318
+ * will need to do another key exchange with all the guests on your keyring.
319
+ */
320
+ selfDestruct(): Promise<void>;
321
+ private getRelayConnectionMutex;
322
+ }
323
+
324
+ /**
325
+ * Status of a previously sent message equals redis TTL.
326
+ * See https://redis.io/commands/ttl.
327
+ * -2 : missing key
328
+ * -1 : key never expires
329
+ * 0+ : key time to live in seconds
330
+ */
331
+ declare enum MessageStatusResponse {
332
+ MissingKey = -2,
333
+ NeverExpires = -1
334
+ }
335
+
336
+ /**
337
+ * Facade singleton to access the NaCl driver.
338
+ * Usage: call instance() with a chosen driver, and store the received object to perform further actions.
339
+ */
340
+ export declare class NaCl {
341
+ private static driverInstance?;
342
+ private constructor();
343
+ static setDefaultInstance(): boolean;
344
+ static setInstance(driver: NaClDriver): boolean;
345
+ static getInstance(): NaClDriver;
346
+ }
347
+
348
+ export declare interface NaClDriver {
349
+ crypto_secretbox_KEYBYTES: number;
350
+ crypto_secretbox_random_nonce(): Promise<Uint8Array>;
351
+ crypto_secretbox(message: Uint8Array, nonce: Uint8Array, key: Uint8Array): Promise<Uint8Array>;
352
+ crypto_secretbox_open(box: Uint8Array, nonce: Uint8Array, key: Uint8Array): Promise<Uint8Array | null>;
353
+ crypto_box_NONCEBYTES: number;
354
+ crypto_box(message: Uint8Array, nonce: Uint8Array, pk: Uint8Array, sk: Uint8Array): Promise<Uint8Array>;
355
+ crypto_box_open(cipher: Uint8Array, nonce: Uint8Array, pk: Uint8Array, sk: Uint8Array): Promise<Uint8Array | null>;
356
+ crypto_box_random_nonce(): Promise<Uint8Array>;
357
+ crypto_box_keypair(): Promise<Keypair>;
358
+ crypto_box_keypair_from_raw_sk(key: Uint8Array): Promise<Keypair>;
359
+ crypto_box_keypair_from_seed(seed: Uint8Array): Promise<Keypair>;
360
+ crypto_hash_sha256(data: Uint8Array): Promise<Uint8Array>;
361
+ h2(data: string | Uint8Array): Promise<Uint8Array>;
362
+ random_bytes(size: number): Promise<Uint8Array>;
363
+ encode_latin1(data: string): Promise<Uint8Array>;
364
+ decode_latin1(data: Uint8Array): Promise<string>;
365
+ encode_utf8(data: string): Promise<Uint8Array>;
366
+ decode_utf8(data: Uint8Array): Promise<string>;
367
+ to_hex(data: Uint8Array): Promise<string>;
368
+ from_hex(data: string): Promise<Uint8Array>;
369
+ }
370
+
371
+ /**
372
+ * Low-level operations with Zax relay
373
+ */
374
+ export declare class Relay {
375
+ url: string;
376
+ private nacl;
377
+ private difficulty;
378
+ private publicKey?;
379
+ private clientToken?;
380
+ private sessionKeys?;
381
+ private tokenExpirationTimeoutHandle?;
382
+ private sessionExpirationTimeoutHandle?;
383
+ constructor(url: string);
384
+ get isConnected(): boolean;
385
+ /**
386
+ * Exchanges tokens with a relay and gets a temp session key for this relay.
387
+ * Returns h₂(signature) and a relay public key
388
+ */
389
+ openConnection(): Promise<RelayConnectionData>;
390
+ /**
391
+ * Sends a client token to a relay and saves a relay token
392
+ */
393
+ private fetchRelayToken;
394
+ /**
395
+ * Completes the handshake and saves a relay pubic key
396
+ */
397
+ private fetchRelayPublicKey;
398
+ /**
399
+ * Attaches a mailbox and fetches number of messages
400
+ */
401
+ prove(payload: EncryptedMessage): Promise<string>;
402
+ encodeMessage(message: string): Promise<EncryptedMessage>;
403
+ decodeMessage<T>(nonce: Base64, ctext: Base64): Promise<T>;
404
+ /**
405
+ * Executes a message/file command on a relay, parses and validates the response
406
+ */
407
+ runCmd(command: RelayCommand, hpk: Base64, message: EncryptedMessage, ctext?: string): Promise<string[]>;
408
+ private getSignature;
409
+ /**
410
+ * Executes a call to a relay and return raw string response
411
+ */
412
+ private httpCall;
413
+ /**
414
+ * Parses relay response and throws an error if its format is unexpected
415
+ */
416
+ private parseResponse;
417
+ /**
418
+ * Compares the expected number of lines in response with what was actually received from a relay
419
+ */
420
+ private validateResponse;
421
+ /**
422
+ * delete token locally before it was removed on server so will reconnect without getting unauthorized error
423
+ */
424
+ private scheduleTokenExpiration;
425
+ clearToken(): void;
426
+ /**
427
+ * established session is valid only for some period need to remove it after it's ttl
428
+ * so relay will reconnect without receiving error from server
429
+ */
430
+ private scheduleSessionExpiration;
431
+ clearSession(): void;
432
+ /**
433
+ * Continuously calculates the nonce until one requested by a relay is found
434
+ */
435
+ private ensureNonceDifficulty;
436
+ /**
437
+ * Returns `true` if the rightmost n bits of a byte are 0.
438
+ * Check whether the rightmost difficulty bits of an Uint8Array are 0, where
439
+ * the lowest indexes of the array represent those rightmost bits. Thus if
440
+ * the difficulty is 17, then array[0] and array[1] should be 0, as should the
441
+ * rightmost bit of array[2]. This is used for our difficulty settings in Zax to
442
+ * reduce burden on a busy server by ensuring clients have to do some
443
+ * additional work during the session handshake
444
+ */
445
+ private arrayZeroBits;
446
+ /**
447
+ * Returns `true` if the rightmost n bits of a byte are 0
448
+ */
449
+ private firstZeroBits;
450
+ }
451
+
452
+ /**
453
+ * Interfaces of Zax relay command requests and responses.
454
+ * See https://github.com/vault12/zax for details.
455
+ *
456
+ * Full technical specification:
457
+ * https://s3-us-west-1.amazonaws.com/vault12/crypto_relay.pdf
458
+ */
459
+ declare enum RelayCommand {
460
+ count = "count",
461
+ upload = "upload",
462
+ download = "download",
463
+ messageStatus = "messageStatus",
464
+ delete = "delete",
465
+ startFileUpload = "startFileUpload",
466
+ uploadFileChunk = "uploadFileChunk",
467
+ downloadFileChunk = "downloadFileChunk",
468
+ fileStatus = "fileStatus",
469
+ deleteFile = "deleteFile"
470
+ }
471
+
472
+ declare interface RelayConnectionData {
473
+ h2Signature: Uint8Array;
474
+ relayPublicKey: Uint8Array;
475
+ }
476
+
477
+ declare interface StartFileUploadResponse {
478
+ uploadID: string;
479
+ max_chunk_size: number;
480
+ storage_token: string;
481
+ skey: Uint8Array;
482
+ }
483
+
484
+ export declare interface StorageDriver {
485
+ get(key: string): Promise<string | null>;
486
+ getMultiple(keys: string[]): Promise<(string | null)[]>;
487
+ set(key: string, value: string | null): Promise<void>;
488
+ setMultiple(values: {
489
+ [key: string]: string | null;
490
+ }): Promise<void>;
491
+ remove(key: string): Promise<void>;
492
+ removeMultiple(keys: string[]): Promise<void>;
493
+ }
494
+
495
+ declare interface UploadFileChunkResponse {
496
+ status: 'OK' | 'NOT_FOUND';
497
+ }
498
+
499
+ export declare class Utils {
500
+ static toBase64(input: Uint8Array): Base64;
501
+ static fromBase64(input: Base64): Uint8Array;
502
+ static encode_latin1(data: string): Uint8Array;
503
+ static decode_latin1(data: Uint8Array): string;
504
+ static toObject(pairs: IterableIterator<[string, unknown]>): {};
505
+ }
506
+
507
+ export declare interface ZaxFileMessage {
508
+ data: FileUploadMetadata;
509
+ time: number;
510
+ senderTag: string;
511
+ uploadID: string;
512
+ nonce: Base64;
513
+ kind: ZaxMessageKind.file;
514
+ }
515
+
516
+ export declare enum ZaxMessageKind {
517
+ message = "message",
518
+ file = "file",
519
+ plain = "plain"
520
+ }
521
+
522
+ export declare type ZaxParsedMessage = ZaxPlainMessage | ZaxFileMessage | ZaxTextMessage;
523
+
524
+ export declare interface ZaxPlainMessage {
525
+ data: string;
526
+ time: number;
527
+ from: Base64;
528
+ nonce: Base64;
529
+ senderTag: undefined;
530
+ kind: ZaxMessageKind.plain;
531
+ }
532
+
533
+ export declare interface ZaxTextMessage {
534
+ /**
535
+ * Decoded object after JSON.parse
536
+ */
537
+ data: string;
538
+ time: number;
539
+ senderTag: string;
540
+ nonce: Base64;
541
+ kind: ZaxMessageKind.message;
542
+ }
543
+
544
+ export { }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "glow.ts",
3
- "version": "1.0.3",
3
+ "version": "1.1.0",
4
4
  "displayName": "Glow.ts",
5
5
  "description": "Client library for interacting with Zax Cryptographic Relay Servers",
6
6
  "keywords": [
@@ -23,39 +23,47 @@
23
23
  "homepage": "https://github.com/vault12/glow.ts#readme",
24
24
  "license": "MIT",
25
25
  "scripts": {
26
- "clean": "rm -rf dist/",
27
- "build:esm": "tsc",
28
- "build:commonjs": "tsc -p ./tscconfig.cjs.json",
29
- "build": "npm run clean && npm run build:esm && npm run build:commonjs",
26
+ "build": "vite build",
27
+ "dev": "vite build --watch",
30
28
  "prepublishOnly": "npm run build",
31
- "lint": "eslint 'src/**'",
32
- "lint:fix": "eslint 'src/**' --fix",
29
+ "lint": "eslint",
30
+ "lint:fix": "eslint --fix",
33
31
  "test": "jest",
34
- "test:coverage": "jest --coverage",
35
- "test:watch": "jest --watch"
32
+ "test:jsdom": "jest --selectProjects jsdom",
33
+ "test:node": "jest --selectProjects node",
34
+ "test:coverage": "jest --selectProjects node --coverage",
35
+ "test:watch": "jest --selectProjects node --watch"
36
36
  },
37
- "main": "dist/cjs/index.js",
38
- "module": "dist/esm/index.js",
39
- "types": "dist/types/index.d.ts",
37
+ "type": "module",
40
38
  "files": [
41
- "dist/**/*"
39
+ "dist"
42
40
  ],
41
+ "exports": {
42
+ ".": {
43
+ "types": "./dist/index.d.ts",
44
+ "import": "./dist/glow.es.js",
45
+ "require": "./dist/glow.cjs.js"
46
+ }
47
+ },
43
48
  "dependencies": {
44
- "async-mutex": "0.3.2",
45
- "axios": "0.28.0",
46
- "js-sha256": "0.9.0",
49
+ "async-mutex": "0.5.0",
47
50
  "tweetnacl": "1.0.3"
48
51
  },
49
52
  "devDependencies": {
50
- "@types/jest": "27.4.0",
51
- "@typescript-eslint/eslint-plugin": "5.12.0",
52
- "@typescript-eslint/parser": "5.12.0",
53
- "axios-mock-adapter": "1.20.0",
54
- "eslint": "8.9.0",
55
- "jest": "27.5.1",
56
- "jest-localstorage-mock": "2.4.19",
57
- "ts-jest": "27.1.3",
58
- "ts-node": "10.5.0",
59
- "typescript": "4.5.5"
53
+ "@eslint/js": "9.25.1",
54
+ "@jest/types": "29.6.3",
55
+ "@microsoft/api-extractor": "7.52.8",
56
+ "@types/jest": "29.5.14",
57
+ "@types/node": "22.15.3",
58
+ "eslint": "9.25.1",
59
+ "jest": "29.7.0",
60
+ "jest-environment-jsdom": "29.7.0",
61
+ "jest-localstorage-mock": "2.4.26",
62
+ "ts-jest": "29.3.2",
63
+ "ts-node": "10.9.2",
64
+ "typescript": "5.8.3",
65
+ "typescript-eslint": "8.31.1",
66
+ "unplugin-dts": "1.0.0-beta.3",
67
+ "vite": "7.0.2"
60
68
  }
61
69
  }
@@ -1,18 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.config = void 0;
4
- const sessionTimeoutBuffer = 30 * 1000;
5
- exports.config = {
6
- NONCE_TAG: '__nc',
7
- SKEY_TAG: 'storage_key',
8
- STORAGE_ROOT: '.v1.stor.vlt12',
9
- // Relay tokens, keys and hashes are 32 bytes
10
- RELAY_TOKEN_LEN: 32,
11
- // 5 min - Token expiration on the server side, matched with config.x.relay.token_timeout on Zax server
12
- RELAY_TOKEN_TIMEOUT: 5 * 60 * 1000 - sessionTimeoutBuffer,
13
- // 20 min - Session expiration on the server side, matched with config.x.relay.session_timeout on Zax server
14
- RELAY_SESSION_TIMEOUT: 20 * 60 * 1000 - sessionTimeoutBuffer,
15
- // 5 sec - Ajax request timeout
16
- RELAY_AJAX_TIMEOUT: 5 * 1000
17
- };
18
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/config.ts"],"names":[],"mappings":";;;AAAA,MAAM,oBAAoB,GAAG,EAAE,GAAG,IAAI,CAAC;AAE1B,QAAA,MAAM,GAAG;IACpB,SAAS,EAAE,MAAM;IACjB,QAAQ,EAAE,aAAa;IACvB,YAAY,EAAE,gBAAgB;IAC9B,6CAA6C;IAC7C,eAAe,EAAE,EAAE;IACnB,uGAAuG;IACvG,mBAAmB,EAAE,CAAC,GAAG,EAAE,GAAG,IAAI,GAAG,oBAAoB;IACzD,4GAA4G;IAC5G,qBAAqB,EAAE,EAAE,GAAG,EAAE,GAAG,IAAI,GAAG,oBAAoB;IAC5D,+BAA+B;IAC/B,kBAAkB,EAAE,CAAC,GAAG,IAAI;CAC7B,CAAC"}