internxt-crypto 0.0.13 → 1.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.
Files changed (154) hide show
  1. package/README.md +44 -72
  2. package/dist/aes-B8TA-JKq.mjs +49 -0
  3. package/dist/aes-B8TA-JKq.mjs.map +1 -0
  4. package/dist/aes-CuW_SPl-.js +67 -0
  5. package/dist/aes-CuW_SPl-.js.map +1 -0
  6. package/dist/asymmetric-crypto.d.mts +8 -31
  7. package/dist/asymmetric-crypto.d.mts.map +1 -1
  8. package/dist/asymmetric-crypto.d.ts +8 -31
  9. package/dist/asymmetric-crypto.d.ts.map +1 -1
  10. package/dist/asymmetric-crypto.js +30 -7
  11. package/dist/asymmetric-crypto.js.map +1 -0
  12. package/dist/asymmetric-crypto.mjs +28 -2
  13. package/dist/asymmetric-crypto.mjs.map +1 -0
  14. package/dist/constants.d.mts +7 -14
  15. package/dist/constants.d.mts.map +1 -1
  16. package/dist/constants.d.ts +7 -14
  17. package/dist/constants.d.ts.map +1 -1
  18. package/dist/constants.js +11 -25
  19. package/dist/constants.js.map +1 -1
  20. package/dist/constants.mjs +7 -14
  21. package/dist/constants.mjs.map +1 -1
  22. package/dist/core-Bj26rNdA.js +227 -0
  23. package/dist/core-Bj26rNdA.js.map +1 -0
  24. package/dist/core-pEGygy6S.mjs +173 -0
  25. package/dist/core-pEGygy6S.mjs.map +1 -0
  26. package/dist/derive-key.d.mts +1 -74
  27. package/dist/derive-key.d.mts.map +1 -1
  28. package/dist/derive-key.d.ts +1 -74
  29. package/dist/derive-key.d.ts.map +1 -1
  30. package/dist/derive-key.js +3 -11
  31. package/dist/derive-key.mjs +2 -2
  32. package/dist/derive-password.d.mts +22 -0
  33. package/dist/derive-password.d.mts.map +1 -0
  34. package/dist/derive-password.d.ts +22 -0
  35. package/dist/derive-password.d.ts.map +1 -0
  36. package/dist/derive-password.js +5 -0
  37. package/dist/derive-password.mjs +3 -0
  38. package/dist/deriveKeysFromKey-C4McqO6_.js +47 -0
  39. package/dist/deriveKeysFromKey-C4McqO6_.js.map +1 -0
  40. package/dist/deriveKeysFromKey-DPU_h7wr.mjs +35 -0
  41. package/dist/deriveKeysFromKey-DPU_h7wr.mjs.map +1 -0
  42. package/dist/{deriveKeysFromPassword-Ko7NxkHM.js → deriveKeysFromPassword-C7xAGGsh.js} +5 -177
  43. package/dist/deriveKeysFromPassword-C7xAGGsh.js.map +1 -0
  44. package/dist/{deriveKeysFromPassword-DJRWZ8Rw.mjs → deriveKeysFromPassword-DXgSvTNC.mjs} +7 -131
  45. package/dist/deriveKeysFromPassword-DXgSvTNC.mjs.map +1 -0
  46. package/dist/email-crypto.d.mts +24 -46
  47. package/dist/email-crypto.d.mts.map +1 -1
  48. package/dist/email-crypto.d.ts +24 -46
  49. package/dist/email-crypto.d.ts.map +1 -1
  50. package/dist/email-crypto.js +121 -12
  51. package/dist/email-crypto.js.map +1 -0
  52. package/dist/email-crypto.mjs +115 -2
  53. package/dist/email-crypto.mjs.map +1 -0
  54. package/dist/email-search.d.mts +18 -18
  55. package/dist/email-search.d.mts.map +1 -1
  56. package/dist/email-search.d.ts +18 -18
  57. package/dist/email-search.d.ts.map +1 -1
  58. package/dist/email-search.js +25 -597
  59. package/dist/email-search.mjs +2 -573
  60. package/dist/{emailEncryptionKey-27mIHh18.mjs → emailEncryptionKey-BtSPYd9M.mjs} +23 -46
  61. package/dist/emailEncryptionKey-BtSPYd9M.mjs.map +1 -0
  62. package/dist/{emailEncryptionKey-DbaDAdoW.js → emailEncryptionKey-C4X1Bwy4.js} +22 -45
  63. package/dist/emailEncryptionKey-C4X1Bwy4.js.map +1 -0
  64. package/dist/{genID-3Er5IowC.mjs → genID-D08K7JPr.mjs} +4 -40
  65. package/dist/genID-D08K7JPr.mjs.map +1 -0
  66. package/dist/{genID-YJSl3YhL.js → genID-cWOPmspk.js} +2 -50
  67. package/dist/genID-cWOPmspk.js.map +1 -0
  68. package/dist/hash.d.mts +24 -36
  69. package/dist/hash.d.mts.map +1 -1
  70. package/dist/hash.d.ts +24 -36
  71. package/dist/hash.d.ts.map +1 -1
  72. package/dist/hash.js +88 -10
  73. package/dist/hash.js.map +1 -0
  74. package/dist/hash.mjs +82 -2
  75. package/dist/hash.mjs.map +1 -0
  76. package/dist/index.d.mts +17 -16
  77. package/dist/index.d.mts.map +1 -1
  78. package/dist/index.d.ts +17 -16
  79. package/dist/index.d.ts.map +1 -1
  80. package/dist/index.js +60 -83
  81. package/dist/index.mjs +13 -11
  82. package/dist/keystore-crypto.d.mts +6 -6
  83. package/dist/keystore-crypto.d.mts.map +1 -1
  84. package/dist/keystore-crypto.d.ts +6 -6
  85. package/dist/keystore-crypto.d.ts.map +1 -1
  86. package/dist/keystore-crypto.js +1 -1
  87. package/dist/keystore-crypto.mjs +1 -1
  88. package/dist/post-quantum-crypto.d.mts +5 -41
  89. package/dist/post-quantum-crypto.d.mts.map +1 -1
  90. package/dist/post-quantum-crypto.d.ts +5 -41
  91. package/dist/post-quantum-crypto.d.ts.map +1 -1
  92. package/dist/post-quantum-crypto.js +49 -16
  93. package/dist/post-quantum-crypto.js.map +1 -0
  94. package/dist/post-quantum-crypto.mjs +46 -2
  95. package/dist/post-quantum-crypto.mjs.map +1 -0
  96. package/dist/search-B9YM3XAA.mjs +587 -0
  97. package/dist/search-B9YM3XAA.mjs.map +1 -0
  98. package/dist/search-DUTm4-rN.js +731 -0
  99. package/dist/search-DUTm4-rN.js.map +1 -0
  100. package/dist/symmetric-crypto.d.mts +13 -42
  101. package/dist/symmetric-crypto.d.mts.map +1 -1
  102. package/dist/symmetric-crypto.d.ts +13 -42
  103. package/dist/symmetric-crypto.d.ts.map +1 -1
  104. package/dist/symmetric-crypto.js +2 -6
  105. package/dist/symmetric-crypto.mjs +2 -2
  106. package/dist/types.d.mts +16 -39
  107. package/dist/types.d.mts.map +1 -1
  108. package/dist/types.d.ts +16 -39
  109. package/dist/types.d.ts.map +1 -1
  110. package/dist/types.js.map +1 -1
  111. package/dist/types.mjs.map +1 -1
  112. package/dist/utils.d.mts +1 -19
  113. package/dist/utils.d.mts.map +1 -1
  114. package/dist/utils.d.ts +1 -19
  115. package/dist/utils.d.ts.map +1 -1
  116. package/dist/utils.js +1 -3
  117. package/dist/utils.mjs +2 -2
  118. package/dist/xwing-CQmQX6hn.mjs +16 -0
  119. package/dist/xwing-CQmQX6hn.mjs.map +1 -0
  120. package/dist/xwing-iRWVRtNE.js +34 -0
  121. package/dist/xwing-iRWVRtNE.js.map +1 -0
  122. package/package.json +4 -2
  123. package/dist/aes-DSDxP8uF.mjs +0 -184
  124. package/dist/aes-DSDxP8uF.mjs.map +0 -1
  125. package/dist/aes-bOrKZuUC.js +0 -226
  126. package/dist/aes-bOrKZuUC.js.map +0 -1
  127. package/dist/deriveKeysFromPassword-DJRWZ8Rw.mjs.map +0 -1
  128. package/dist/deriveKeysFromPassword-Ko7NxkHM.js.map +0 -1
  129. package/dist/email-search.js.map +0 -1
  130. package/dist/email-search.mjs.map +0 -1
  131. package/dist/emailEncryptionKey-27mIHh18.mjs.map +0 -1
  132. package/dist/emailEncryptionKey-DbaDAdoW.js.map +0 -1
  133. package/dist/emailKeys-BJGdkLrg.js +0 -593
  134. package/dist/emailKeys-BJGdkLrg.js.map +0 -1
  135. package/dist/emailKeys-Fp9WR3wl.mjs +0 -509
  136. package/dist/emailKeys-Fp9WR3wl.mjs.map +0 -1
  137. package/dist/genID-3Er5IowC.mjs.map +0 -1
  138. package/dist/genID-YJSl3YhL.js.map +0 -1
  139. package/dist/keys-BfcaiAOv.mjs +0 -90
  140. package/dist/keys-BfcaiAOv.mjs.map +0 -1
  141. package/dist/keys-CinT7kEY.js +0 -125
  142. package/dist/keys-CinT7kEY.js.map +0 -1
  143. package/dist/kyber1024-PpwE1rki.mjs +0 -144
  144. package/dist/kyber1024-PpwE1rki.mjs.map +0 -1
  145. package/dist/kyber1024-jeKS8CXf.js +0 -173
  146. package/dist/kyber1024-jeKS8CXf.js.map +0 -1
  147. package/dist/kyber768-DGBB_RS7.d.ts +0 -32
  148. package/dist/kyber768-DGBB_RS7.d.ts.map +0 -1
  149. package/dist/kyber768-DzIcGg1i.d.mts +0 -32
  150. package/dist/kyber768-DzIcGg1i.d.mts.map +0 -1
  151. package/dist/mac-BMb1F0dN.js +0 -170
  152. package/dist/mac-BMb1F0dN.js.map +0 -1
  153. package/dist/mac-ZpRlx8Fs.mjs +0 -116
  154. package/dist/mac-ZpRlx8Fs.mjs.map +0 -1
@@ -1,574 +1,3 @@
1
- import { CONTEXT_INDEX, DB_LABEL, DB_VERSION, MAX_CACHE_SIZE, MAX_EMAIL_PER_BATCH } from "./constants.mjs";
2
- import { o as deriveSymmetricCryptoKeyFromContext } from "./deriveKeysFromPassword-DJRWZ8Rw.mjs";
3
- import { c as encryptEmailContentSymmetricallyWithKey, l as getAux, s as decryptEmailSymmetrically, u as emailToBinary } from "./emailKeys-Fp9WR3wl.mjs";
4
- import { deleteDB, openDB } from "idb";
5
- import { Index } from "flexsearch";
1
+ import { C as getEmailCount, S as getEmailBatch, _ as enforceMaxEmailNumber, a as addEmailToCache, b as getAndDecryptAllEmails, c as deleteEmailFromCache, d as deleteDatabase, f as deleteEmail, g as encryptAndStoreManyEmail, h as encryptAndStoreEmail, i as searchEmails, l as getEmailFromCache, m as deriveIndexKey, n as buildSearchIndexFromCache, o as addEmailsToCache, p as deleteOldestEmails, r as removeEmailFromSearchIndex, s as createCacheFromDB, t as addEmailToSearchIndex, u as closeDatabase, v as getAllEmailsSortedNewestFirst, w as openDatabase, x as getAndDecryptEmail, y as getAllEmailsSortedOldestFirst } from "./search-B9YM3XAA.mjs";
6
2
 
7
- //#region src/email-search/indexedDB.ts
8
- /**
9
- * Returns IndexedDB database name for the given user
10
- *
11
- * @param userID - The user ID
12
- * @returns The database name
13
- */
14
- const getDatabaseName = (userID) => {
15
- return `ES:${userID}:DB`;
16
- };
17
- /**
18
- * Opens IndexedDB database for the given user
19
- *
20
- * @param userID - The user ID
21
- * @returns The database
22
- */
23
- const openDatabase = async (userID) => {
24
- try {
25
- return openDB(getDatabaseName(userID), DB_VERSION, { upgrade(db) {
26
- if (!db.objectStoreNames.contains(DB_LABEL)) db.createObjectStore(DB_LABEL, { keyPath: "id" }).createIndex("byTime", "params.createdAt");
27
- } });
28
- } catch (error) {
29
- throw new Error(`Cannot open a database for the user ${userID}`, { cause: error });
30
- }
31
- };
32
- /**
33
- * Closes the IndexedDB database
34
- *
35
- * @param esDB - The database
36
- */
37
- const closeDatabase = (esDB) => {
38
- return esDB.close();
39
- };
40
- /**
41
- * Deletes IndexedDB database for the given user
42
- *
43
- * @param userID - The user ID
44
- * @returns The database
45
- */
46
- const deleteDatabase = async (userID) => {
47
- return deleteDB(getDatabaseName(userID));
48
- };
49
- /**
50
- * Derives database encryption key for the given user
51
- *
52
- * @param userID - The user ID
53
- * @returns The symmetric CryptoKey for protecting database
54
- */
55
- const deriveIndexKey = async (baseKey) => {
56
- return deriveSymmetricCryptoKeyFromContext(CONTEXT_INDEX, baseKey);
57
- };
58
- /**
59
- * Encrypts the given email and stores it in the IndexedDB database
60
- *
61
- * @param newEmailToStore - The email for storing
62
- * @param indexKey - The symmetric CryptoKey key for protecting database
63
- * @param esDB - The database
64
- */
65
- const encryptAndStoreEmail = async (newEmailToStore, indexKey, esDB) => {
66
- try {
67
- const aux = getAux(newEmailToStore.params, false);
68
- const encryptedEmail = {
69
- enc: await encryptEmailContentSymmetricallyWithKey(newEmailToStore.body, indexKey, aux, newEmailToStore.id),
70
- params: newEmailToStore.params,
71
- id: newEmailToStore.id
72
- };
73
- await esDB.put(DB_LABEL, encryptedEmail);
74
- } catch (error) {
75
- throw new Error("Cannot encrypt and add the given email to the database", { cause: error });
76
- }
77
- };
78
- /**
79
- * Encrypts the given set of emails and stores it in the IndexedDB database
80
- *
81
- * @param newEmailsToStore - The set of emails for storing
82
- * @param indexKey - The symmetric CryptoKey key for protecting database
83
- * @param esDB - The database
84
- */
85
- const encryptAndStoreManyEmail = async (newEmailsToStore, indexKey, esDB) => {
86
- try {
87
- const encryptedEmails = await Promise.all(newEmailsToStore.map(async (email) => {
88
- const aux = getAux(email.params, false);
89
- return {
90
- enc: await encryptEmailContentSymmetricallyWithKey(email.body, indexKey, aux, email.id),
91
- params: email.params,
92
- id: email.id
93
- };
94
- }));
95
- const tr = esDB.transaction(DB_LABEL, "readwrite");
96
- await Promise.all([...encryptedEmails.map((encEmail) => tr.store.put(encEmail)), tr.done]);
97
- } catch (error) {
98
- throw new Error("Cannot encrypt and add emails to the database", { cause: error });
99
- }
100
- };
101
- /**
102
- * Decrypts the given email
103
- *
104
- * @param indexKey - The symmetric CryptoKey key for protecting database
105
- * @param encryptedEmail - The encrypted email
106
- * @returns The decrypted email
107
- */
108
- const decryptEmail = async (indexKey, encryptedEmail) => {
109
- try {
110
- return {
111
- body: await decryptEmailSymmetrically(indexKey, getAux(encryptedEmail.params, false), encryptedEmail.enc),
112
- params: encryptedEmail.params,
113
- id: encryptedEmail.id
114
- };
115
- } catch (error) {
116
- throw new Error("Cannot decrypt the given email", { cause: error });
117
- }
118
- };
119
- /**
120
- * Fetches the email from the database and decrypts it
121
- *
122
- * @param emailID - The email identifier
123
- * @param indexKey - The symmetric CryptoKey key for protecting database
124
- * @param encryptedEmail - The encrypted email
125
- * @returns The decrypted email
126
- */
127
- const getAndDecryptEmail = async (emailID, indexKey, esDB) => {
128
- try {
129
- const encryptedEmail = await esDB.get(DB_LABEL, emailID);
130
- if (!encryptedEmail) throw new Error(`DB cannot find email with id ${emailID}`);
131
- return decryptEmail(indexKey, encryptedEmail);
132
- } catch (error) {
133
- throw new Error(`Cannot fetch the email ${emailID} from the database`, { cause: error });
134
- }
135
- };
136
- /**
137
- * Fetches all email from the database and decrypts them
138
- *
139
- * @param indexKey - The symmetric CryptoKey key for protecting database
140
- * @param esDB - The database
141
- * @returns The decrypted emails
142
- */
143
- const getAndDecryptAllEmails = async (indexKey, esDB) => {
144
- try {
145
- const encryptedEmails = await esDB.getAll(DB_LABEL);
146
- return (await Promise.all(encryptedEmails.map(async (encEmail) => {
147
- return {
148
- body: await decryptEmailSymmetrically(indexKey, getAux(encEmail.params, false), encEmail.enc),
149
- params: encEmail.params,
150
- id: encEmail.id
151
- };
152
- }))).filter((email) => email !== null);
153
- } catch (error) {
154
- throw new Error("Cannot fetch and decrypt all emails from the database", { cause: error });
155
- }
156
- };
157
- /**
158
- * Deletes the email from the database
159
- *
160
- * @param emailID - The email identifier
161
- * @param esDB - The database
162
- */
163
- const deleteEmail = async (emailID, esDB) => {
164
- await esDB.delete(DB_LABEL, emailID);
165
- };
166
- /**
167
- * Returns the number of stored email
168
- *
169
- * @param esDB - The database
170
- * @returns The number of stored emails
171
- */
172
- const getEmailCount = async (esDB) => {
173
- return await esDB.count(DB_LABEL);
174
- };
175
- /**
176
- * Removes the given number of oldests emails from the database
177
- *
178
- * @param emailsToDelete - The number of emails to delete
179
- * @param esDB - The database
180
- */
181
- const deleteOldestEmails = async (emailsToDelete, esDB) => {
182
- try {
183
- const tx = esDB.transaction(DB_LABEL, "readwrite");
184
- let cursor = await tx.store.index("byTime").openCursor();
185
- let deletedCount = 0;
186
- while (cursor && deletedCount < emailsToDelete) {
187
- await cursor.delete();
188
- deletedCount++;
189
- cursor = await cursor.continue();
190
- }
191
- await tx.done;
192
- } catch (error) {
193
- throw new Error(`Cannot delete ${emailsToDelete} oldests emails from the database`, { cause: error });
194
- }
195
- };
196
- /**
197
- * Enforces the maximum email number in the database
198
- *
199
- * @param esDB - The database
200
- * @param max - The maximum allowed number of emails
201
- */
202
- const enforceMaxEmailNumber = async (esDB, max) => {
203
- try {
204
- const currentCount = await getEmailCount(esDB);
205
- if (currentCount <= max) return;
206
- await deleteOldestEmails(currentCount - max, esDB);
207
- } catch (error) {
208
- throw new Error(`Cannot enforce the maximum of ${max} emails on the database`, { cause: error });
209
- }
210
- };
211
- /**
212
- * Fetches all emails from the database, decrypts them and sortes the results in the specified order
213
- *
214
- * @param esDB - The database
215
- * @param indexKey - The symmetric CryptoKey key for protecting database
216
- * @param direction - The order of sorting. If 'next' - oldest first, if 'prev' - newest first
217
- * @returns Decryped emails in the specified order
218
- */
219
- const fetchEmails = async (esDB, indexKey, direction) => {
220
- try {
221
- const index = esDB.transaction(DB_LABEL, "readonly").store.index("byTime");
222
- const encryptedEmails = [];
223
- let cursor = await index.openCursor(null, direction);
224
- while (cursor) {
225
- encryptedEmails.push(cursor.value);
226
- cursor = await cursor.continue();
227
- }
228
- return await Promise.all(encryptedEmails.map((encryptedEmail) => decryptEmail(indexKey, encryptedEmail)));
229
- } catch (error) {
230
- throw new Error("Cannot fetch emails from database", { cause: error });
231
- }
232
- };
233
- /**
234
- * Fetches all emails from the database, decrypts them and sortes the results based on the creation time (newest first)
235
- *
236
- * @param esDB - The database
237
- * @param indexKey - The symmetric CryptoKey key for protecting database
238
- * @returns The number of stored emails
239
- */
240
- const getAllEmailsSortedNewestFirst = async (esDB, indexKey) => {
241
- return fetchEmails(esDB, indexKey, "prev");
242
- };
243
- /**
244
- * Fetches all emails from the database, decrypts them and sortes the results based on the creation time (oldest first)
245
- *
246
- * @param esDB - The database
247
- * @param indexKey - The symmetric CryptoKey key for protecting database
248
- * @returns The number of stored emails
249
- */
250
- const getAllEmailsSortedOldestFirst = async (esDB, indexKey) => {
251
- return fetchEmails(esDB, indexKey, "next");
252
- };
253
- /**
254
- * Fetches a batch of emails from the database, decrypts them and sortes the results based on the creation time (newest first)
255
- *
256
- * @param esDB - The database
257
- * @param indexKey - The symmetric CryptoKey key for protecting database
258
- * @param batchSize - The size of the batch
259
- * @param startCursor - The starting point (optional). If not given, starts from the beginning
260
- * @returns The number of stored emails
261
- */
262
- const getEmailBatch = async (esDB, indexKey, batchSize, startCursor) => {
263
- try {
264
- const index = esDB.transaction(DB_LABEL, "readonly").store.index("byTime");
265
- const encryptedEmails = [];
266
- let cursor;
267
- if (startCursor) {
268
- const range = IDBKeyRange.upperBound(startCursor, true);
269
- cursor = await index.openCursor(range, "prev");
270
- } else cursor = await index.openCursor(null, "prev");
271
- let count = 0;
272
- let nextCursor;
273
- while (cursor && count < batchSize) {
274
- encryptedEmails.push(cursor.value);
275
- nextCursor = cursor.key;
276
- count++;
277
- cursor = await cursor.continue();
278
- }
279
- return {
280
- emails: await Promise.all(encryptedEmails.map((encryptedEmail) => decryptEmail(indexKey, encryptedEmail))),
281
- nextCursor: count === batchSize ? nextCursor : void 0
282
- };
283
- } catch (error) {
284
- throw new Error(`Cannot fetch email batch of ${batchSize} from the database`, { cause: error });
285
- }
286
- };
287
-
288
- //#endregion
289
- //#region src/email-search/mailCache.ts
290
- /**
291
- * Estimates the email size in the memory
292
- *
293
- * @param email - The email
294
- * @returns The estimation of the email size
295
- */
296
- function sizeOfEmail(email) {
297
- return emailToBinary(email).byteLength;
298
- }
299
- /**
300
- * Creates an empty cache variable
301
- *
302
- * @returns The empty cache
303
- */
304
- function createEmptyCache() {
305
- return {
306
- esCache: /* @__PURE__ */ new Map(),
307
- cacheSize: 0,
308
- isCacheLimited: false,
309
- isCacheReady: true
310
- };
311
- }
312
- /**
313
- * Fetches all emails from the database in batches and cahces them
314
- *
315
- * @param indexKey - The symmetric CryptoKey key for protecting database
316
- * @param esCache - The cache to add emails too
317
- * @param esDB - The database
318
- */
319
- const createCacheFromDB = async (indexKey, esDB) => {
320
- const esCache = createEmptyCache();
321
- esCache.isCacheReady = false;
322
- try {
323
- const count = await getEmailCount(esDB);
324
- if (!count) {
325
- esCache.isCacheReady = true;
326
- return esCache;
327
- }
328
- if (count <= MAX_EMAIL_PER_BATCH) addEmailsToCache(await getAllEmailsSortedNewestFirst(esDB, indexKey), esCache);
329
- else {
330
- let nextCursor = void 0;
331
- let cacheFull = false;
332
- while (!cacheFull) {
333
- const { emails, nextCursor: newCursor } = await getEmailBatch(esDB, indexKey, MAX_EMAIL_PER_BATCH, nextCursor);
334
- if (!newCursor || !emails.length) break;
335
- nextCursor = newCursor;
336
- if (!addEmailsToCache(emails, esCache)) cacheFull = true;
337
- }
338
- }
339
- return esCache;
340
- } catch (error) {
341
- throw new Error(`Email caching failed: ${error}`, { cause: error });
342
- }
343
- };
344
- /**
345
- * Gets an email from the cache
346
- *
347
- * @param emailID - The email identifier
348
- * @param esCache - The email cache
349
- * @returns The found email or throws an error
350
- */
351
- const getEmailFromCache = async (emailID, esCache) => {
352
- const email = esCache.esCache.get(emailID);
353
- if (!email) throw new Error(`Email not found in cache for ID: ${emailID}`);
354
- return email;
355
- };
356
- /**
357
- * Removes the email from cache
358
- *
359
- * @param emailID - The email identifier
360
- * @param esCache - The email cache
361
- */
362
- const deleteEmailFromCache = async (emailID, esCache) => {
363
- try {
364
- const size = sizeOfEmail(await getEmailFromCache(emailID, esCache));
365
- if (esCache.esCache.delete(emailID)) esCache.cacheSize -= size;
366
- } catch (error) {
367
- throw new Error(`Failed to delete email with ID ${emailID}`, { cause: error });
368
- }
369
- };
370
- /**
371
- * Adds emails to the cache
372
- *
373
- * @param emails - The emails to add
374
- * @param esCache - The email cache
375
- * @returns TRUE if all emails were added sucessfully, or FALSE and error reason.
376
- */
377
- function addEmailsToCache(emails, esCache) {
378
- try {
379
- for (const email of emails) {
380
- const result = addEmailToCache(email, esCache);
381
- if (!result.success) return result;
382
- }
383
- return { success: true };
384
- } catch (error) {
385
- throw new Error("Failed to add emails to the cache", { cause: error });
386
- }
387
- }
388
- /**
389
- * Adds email to the cache
390
- *
391
- * @param email - The email to add
392
- * @param esCache - The email cache
393
- * @returns TRUE if the email was added sucessfully, or FALSE and error reason.
394
- */
395
- const addEmailToCache = (email, esCache) => {
396
- try {
397
- if (esCache.esCache.has(email.id)) return {
398
- success: false,
399
- reason: "email already exists in cache"
400
- };
401
- const emailSize = sizeOfEmail(email);
402
- if (esCache.cacheSize + emailSize > MAX_CACHE_SIZE) {
403
- esCache.isCacheLimited = true;
404
- return {
405
- success: false,
406
- reason: "hit cache limit"
407
- };
408
- }
409
- esCache.esCache.set(email.id, email);
410
- esCache.cacheSize += emailSize;
411
- return { success: true };
412
- } catch (error) {
413
- throw new Error("Failed to add email to the cache", { cause: error });
414
- }
415
- };
416
-
417
- //#endregion
418
- //#region src/email-search/search.ts
419
- const SUBJECT_OPTIONS = {
420
- preset: "match",
421
- tokenize: "forward",
422
- resolution: 9,
423
- minlength: 2,
424
- optimize: true,
425
- fastupdate: true,
426
- cache: true
427
- };
428
- const BODY_OPTIONS = {
429
- ...SUBJECT_OPTIONS,
430
- minlength: 3,
431
- resolution: 6
432
- };
433
- const FROM_OPTIONS = {
434
- ...SUBJECT_OPTIONS,
435
- tokenize: "strict",
436
- minlength: 1
437
- };
438
- const TO_OPTIONS = {
439
- ...SUBJECT_OPTIONS,
440
- tokenize: "strict",
441
- minlength: 1
442
- };
443
- /**
444
- * Creates new email search index
445
- *
446
- * @returns The email search index
447
- */
448
- const createSearchIndex = () => ({
449
- subjectIndex: new Index(SUBJECT_OPTIONS),
450
- bodyIndex: new Index(BODY_OPTIONS),
451
- fromIndex: new Index(FROM_OPTIONS),
452
- toIndex: new Index(TO_OPTIONS),
453
- isReady: false
454
- });
455
- /**
456
- * Adds the given email to the email search index
457
- *
458
- * @param email - The email to add
459
- * @param searchIndex - The email search index
460
- */
461
- const addEmailToSearchIndex = (email, searchIndex) => {
462
- try {
463
- const emailId = email.id;
464
- if (email.params.subject) searchIndex.subjectIndex.add(emailId, email.params.subject);
465
- if (email.body?.text) searchIndex.bodyIndex.add(emailId, email.body.text);
466
- if (email.params.sender) {
467
- const senderText = `${email.params.sender.name || ""} ${email.params.sender.email || ""}`.trim();
468
- searchIndex.fromIndex.add(emailId, senderText);
469
- }
470
- const recipientsText = (email.params.recipients?.length ? email.params.recipients : [email.params.recipient]).map((recipient) => `${recipient.name || ""} ${recipient.email || ""}`.trim()).join(" ");
471
- searchIndex.toIndex.add(emailId, recipientsText);
472
- } catch (error) {
473
- throw new Error("Failed to add email to the search index", { cause: error });
474
- }
475
- };
476
- /**
477
- * Removes the email from the email search index
478
- *
479
- * @param emailID - The email identifier
480
- * @param searchIndex - The email search index
481
- */
482
- const removeEmailFromSearchIndex = (emailID, searchIndex) => {
483
- try {
484
- searchIndex.subjectIndex.remove(emailID);
485
- searchIndex.bodyIndex.remove(emailID);
486
- searchIndex.fromIndex.remove(emailID);
487
- searchIndex.toIndex.remove(emailID);
488
- } catch (error) {
489
- throw new Error(`Failed to remove email with ID ${emailID} from the search index`, { cause: error });
490
- }
491
- };
492
- /**
493
- * Buils the email search index from the email cache
494
- *
495
- * @param esCache - The email cache
496
- * @returns The email search index
497
- */
498
- const buildSearchIndexFromCache = async (esCache) => {
499
- try {
500
- const searchIndex = createSearchIndex();
501
- searchIndex.isReady = false;
502
- for (const email of esCache.esCache.values()) addEmailToSearchIndex(email, searchIndex);
503
- searchIndex.isReady = true;
504
- return searchIndex;
505
- } catch (error) {
506
- throw new Error("Failed build an email search index from the cache", { cause: error });
507
- }
508
- };
509
- /**
510
- * Searches in teh
511
- *
512
- * @param query - The string to search for
513
- * @param esCache - The email cache
514
- * @param searchIndex - The email search index
515
- * @param opetions - The optional search limitations
516
- * @returns The result of the email search (emails ans their corresponding result weights)
517
- */
518
- const searchEmails = async (query, esCache, searchIndex, options = {}) => {
519
- try {
520
- if (!searchIndex.isReady || !query.trim()) return [];
521
- const { fields = [
522
- "subject",
523
- "body",
524
- "from",
525
- "to"
526
- ], limit = 50, boost = {
527
- subject: 3,
528
- body: 1,
529
- from: 2,
530
- to: 2
531
- } } = options;
532
- const results = /* @__PURE__ */ new Map();
533
- const searchPromises = fields.map(async (field) => {
534
- let fieldResults;
535
- switch (field) {
536
- case "subject":
537
- fieldResults = await searchIndex.subjectIndex.searchAsync(query);
538
- break;
539
- case "body":
540
- fieldResults = await searchIndex.bodyIndex.searchAsync(query);
541
- break;
542
- case "from":
543
- fieldResults = await searchIndex.fromIndex.searchAsync(query);
544
- break;
545
- case "to":
546
- fieldResults = await searchIndex.toIndex.searchAsync(query);
547
- break;
548
- default: return;
549
- }
550
- const fieldBoost = boost[field] || 1;
551
- fieldResults.forEach((emailId) => {
552
- const currentScore = results.get(String(emailId)) || 0;
553
- results.set(String(emailId), currentScore + fieldBoost);
554
- });
555
- });
556
- await Promise.all(searchPromises);
557
- const emailResults = [];
558
- for (const [emailId, score] of results) {
559
- const email = esCache.esCache.get(emailId);
560
- if (email) emailResults.push({
561
- email,
562
- score
563
- });
564
- }
565
- emailResults.sort((a, b) => (b.score || 0) - (a.score || 0));
566
- return emailResults.slice(0, limit);
567
- } catch (error) {
568
- throw new Error("Email search failed", { cause: error });
569
- }
570
- };
571
-
572
- //#endregion
573
- export { addEmailToCache, addEmailToSearchIndex, addEmailsToCache, buildSearchIndexFromCache, closeDatabase, createCacheFromDB, deleteDatabase, deleteEmail, deleteEmailFromCache, deleteOldestEmails, deriveIndexKey, encryptAndStoreEmail, encryptAndStoreManyEmail, enforceMaxEmailNumber, getAllEmailsSortedNewestFirst, getAllEmailsSortedOldestFirst, getAndDecryptAllEmails, getAndDecryptEmail, getEmailBatch, getEmailCount, getEmailFromCache, openDatabase, removeEmailFromSearchIndex, searchEmails };
574
- //# sourceMappingURL=email-search.mjs.map
3
+ export { addEmailToCache, addEmailToSearchIndex, addEmailsToCache, buildSearchIndexFromCache, closeDatabase, createCacheFromDB, deleteDatabase, deleteEmail, deleteEmailFromCache, deleteOldestEmails, deriveIndexKey, encryptAndStoreEmail, encryptAndStoreManyEmail, enforceMaxEmailNumber, getAllEmailsSortedNewestFirst, getAllEmailsSortedOldestFirst, getAndDecryptAllEmails, getAndDecryptEmail, getEmailBatch, getEmailCount, getEmailFromCache, openDatabase, removeEmailFromSearchIndex, searchEmails };
@@ -1,38 +1,28 @@
1
- import { AES_KEY_BIT_LENGTH, CONTEXT_ENC_KEYSTORE, CONTEXT_RECOVERY } from "./constants.mjs";
2
- import { a as importPublicKey, i as importPrivateKey, t as exportPrivateKey } from "./keys-BfcaiAOv.mjs";
3
- import { a as genMnemonic, c as publicKeyToBase64, f as uint8ArrayToBase64, l as UTF8ToUint8, o as mnemonicToBytes, u as base64ToUint8Array } from "./genID-3Er5IowC.mjs";
4
- import { n as getBytesFromData } from "./mac-ZpRlx8Fs.mjs";
5
- import { n as encryptSymmetrically, t as decryptSymmetrically } from "./aes-DSDxP8uF.mjs";
6
- import { o as deriveSymmetricCryptoKeyFromContext } from "./deriveKeysFromPassword-DJRWZ8Rw.mjs";
7
- import { t as generateEmailKeys } from "./emailKeys-Fp9WR3wl.mjs";
1
+ import { CONTEXT_ENC_KEYSTORE, CONTEXT_RECOVERY } from "./constants.mjs";
2
+ import { a as genMnemonic, c as base64ToUint8Array, o as mnemonicToBytes, s as UTF8ToUint8, u as uint8ArrayToBase64 } from "./genID-D08K7JPr.mjs";
3
+ import { t as deriveSymmetricKeyFromContext } from "./deriveKeysFromKey-DPU_h7wr.mjs";
4
+ import { n as encryptSymmetrically, t as decryptSymmetrically } from "./aes-B8TA-JKq.mjs";
5
+ import { r as genHybridKeys } from "./xwing-CQmQX6hn.mjs";
8
6
  import { KeystoreType } from "./types.mjs";
9
7
 
10
8
  //#region src/keystore-crypto/core.ts
11
9
  /**
12
- * Encrypts the keystore content using symmetric encryption
10
+ * Encrypts the user's hybrid key using symmetric encryption to get a keystore
13
11
  *
14
12
  * @param secretKey - The symmetric key to encrypt the keystore content
15
- * @param content - The content of the keystore
16
- * @param userID - The ID of the user
17
- * @param tag - The keystore type-specific tag string
18
- * @returns The encrypted keystore content
13
+ * @param key - The hybrid key pair
14
+ * @param userEmail - The email of the user
15
+ * @param type - The keystore type
16
+ * @returns The encrypted keystore
19
17
  */
20
18
  async function encryptKeystoreContent(secretKey, keys, userEmail, type) {
21
19
  try {
22
20
  const aux = UTF8ToUint8(userEmail + type);
23
- const publicKeys = await publicKeyToBase64(keys.publicKeys);
24
- const kyberPrivateKeyEnc = await encryptSymmetrically(secretKey, keys.privateKeys.kyberPrivateKey, aux);
25
- const eccPrivateKeyEnc = await encryptSymmetrically(secretKey, await exportPrivateKey(keys.privateKeys.eccPrivateKey), aux);
26
21
  return {
27
22
  userEmail,
28
23
  type,
29
- encryptedKeys: {
30
- publicKeys,
31
- privateKeys: {
32
- kyberPrivateKeyBase64: uint8ArrayToBase64(kyberPrivateKeyEnc),
33
- eccPrivateKeyBase64: uint8ArrayToBase64(eccPrivateKeyEnc)
34
- }
35
- }
24
+ publicKey: uint8ArrayToBase64(keys.publicKey),
25
+ privateKeyEncrypted: uint8ArrayToBase64(await encryptSymmetrically(secretKey, keys.secretKey, aux))
36
26
  };
37
27
  } catch (error) {
38
28
  throw new Error("Failed to encrypt keystore content", { cause: error });
@@ -41,28 +31,16 @@ async function encryptKeystoreContent(secretKey, keys, userEmail, type) {
41
31
  /**
42
32
  * Decrypts the keystore content using symmetric encryption
43
33
  *
44
- * @param secretKey - The symmetric key to decrypt the keystore content
34
+ * @param kesytoreOpeningKey - The symmetric key to decrypt the keystore content
45
35
  * @param encryptedKeys - The encrypted keystore content
46
- * @param userEmail - The ID of the user
47
- * @param tag - The keystore type-specific tag string
48
- * @returns The decrypted keystore content
36
+ * @returns The decrypted hybrid key pair contained in the keystore
49
37
  */
50
- async function decryptKeystoreContent(secretKey, encryptedKeystore) {
38
+ async function decryptKeystoreContent(kesytoreOpeningKey, encryptedKeystore) {
51
39
  try {
52
40
  const aux = UTF8ToUint8(encryptedKeystore.userEmail + encryptedKeystore.type);
53
- const kyberPublicKey = base64ToUint8Array(encryptedKeystore.encryptedKeys.publicKeys.kyberPublicKeyBase64);
54
- const eccPublicKey = await importPublicKey(base64ToUint8Array(encryptedKeystore.encryptedKeys.publicKeys.eccPublicKeyBase64));
55
- const kyberPrivateKey = await decryptSymmetrically(secretKey, base64ToUint8Array(encryptedKeystore.encryptedKeys.privateKeys.kyberPrivateKeyBase64), aux);
56
- const eccPrivateKey = await importPrivateKey(await decryptSymmetrically(secretKey, base64ToUint8Array(encryptedKeystore.encryptedKeys.privateKeys.eccPrivateKeyBase64), aux));
57
41
  return {
58
- publicKeys: {
59
- kyberPublicKey,
60
- eccPublicKey
61
- },
62
- privateKeys: {
63
- kyberPrivateKey,
64
- eccPrivateKey
65
- }
42
+ publicKey: base64ToUint8Array(encryptedKeystore.publicKey),
43
+ secretKey: await decryptSymmetrically(kesytoreOpeningKey, base64ToUint8Array(encryptedKeystore.privateKeyEncrypted), aux)
66
44
  };
67
45
  } catch (error) {
68
46
  throw new Error("Failed to decrypt keystore content", { cause: error });
@@ -75,8 +53,7 @@ async function decryptKeystoreContent(secretKey, encryptedKeystore) {
75
53
  * @returns The derived secret key for protecting the recovery keystore
76
54
  */
77
55
  async function deriveRecoveryKey(recoveryCodes) {
78
- const recoverCodesArray = mnemonicToBytes(recoveryCodes);
79
- return deriveSymmetricCryptoKeyFromContext(CONTEXT_RECOVERY, getBytesFromData(AES_KEY_BIT_LENGTH / 8, recoverCodesArray));
56
+ return deriveSymmetricKeyFromContext(CONTEXT_RECOVERY, mnemonicToBytes(recoveryCodes));
80
57
  }
81
58
  /**
82
59
  * Derives a secret key for protecting the encryption keystore
@@ -85,21 +62,21 @@ async function deriveRecoveryKey(recoveryCodes) {
85
62
  * @returns The derived secret key for protecting the encryption keystore
86
63
  */
87
64
  async function deriveEncryptionKeystoreKey(baseKey) {
88
- return deriveSymmetricCryptoKeyFromContext(CONTEXT_ENC_KEYSTORE, baseKey);
65
+ return deriveSymmetricKeyFromContext(CONTEXT_ENC_KEYSTORE, baseKey);
89
66
  }
90
67
 
91
68
  //#endregion
92
69
  //#region src/keystore-crypto/emailEncryptionKey.ts
93
70
  /**
94
- * Generates email keys and creates encrypted main and recovery keystores
71
+ * Generates hybrid keys and creates encrypted main and recovery keystores
95
72
  * The main keystore encryption key is derived from the base key (stored in session storage)
96
73
  * The recovery keystore encryption key is derived from the recovery codes
97
74
  *
98
- * @returns The encryption and recovery keystores, recovery codes and email keys
75
+ * @returns The encryption and recovery keystores, recovery codes and hybrid keys
99
76
  */
100
77
  async function createEncryptionAndRecoveryKeystores(userEmail, baseKey) {
101
78
  try {
102
- const keys = await generateEmailKeys();
79
+ const keys = genHybridKeys();
103
80
  const encryptionKeystore = await encryptKeystoreContent(await deriveEncryptionKeystoreKey(baseKey), keys, userEmail, KeystoreType.ENCRYPTION);
104
81
  const recoveryCodes = genMnemonic();
105
82
  return {
@@ -147,4 +124,4 @@ async function openRecoveryKeystore(recoveryCodes, encryptedKeystore) {
147
124
 
148
125
  //#endregion
149
126
  export { openEncryptionKeystore as n, openRecoveryKeystore as r, createEncryptionAndRecoveryKeystores as t };
150
- //# sourceMappingURL=emailEncryptionKey-27mIHh18.mjs.map
127
+ //# sourceMappingURL=emailEncryptionKey-BtSPYd9M.mjs.map