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.
- package/README.md +44 -72
- package/dist/aes-B8TA-JKq.mjs +49 -0
- package/dist/aes-B8TA-JKq.mjs.map +1 -0
- package/dist/aes-CuW_SPl-.js +67 -0
- package/dist/aes-CuW_SPl-.js.map +1 -0
- package/dist/asymmetric-crypto.d.mts +8 -31
- package/dist/asymmetric-crypto.d.mts.map +1 -1
- package/dist/asymmetric-crypto.d.ts +8 -31
- package/dist/asymmetric-crypto.d.ts.map +1 -1
- package/dist/asymmetric-crypto.js +30 -7
- package/dist/asymmetric-crypto.js.map +1 -0
- package/dist/asymmetric-crypto.mjs +28 -2
- package/dist/asymmetric-crypto.mjs.map +1 -0
- package/dist/constants.d.mts +7 -14
- package/dist/constants.d.mts.map +1 -1
- package/dist/constants.d.ts +7 -14
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +11 -25
- package/dist/constants.js.map +1 -1
- package/dist/constants.mjs +7 -14
- package/dist/constants.mjs.map +1 -1
- package/dist/core-Bj26rNdA.js +227 -0
- package/dist/core-Bj26rNdA.js.map +1 -0
- package/dist/core-pEGygy6S.mjs +173 -0
- package/dist/core-pEGygy6S.mjs.map +1 -0
- package/dist/derive-key.d.mts +1 -74
- package/dist/derive-key.d.mts.map +1 -1
- package/dist/derive-key.d.ts +1 -74
- package/dist/derive-key.d.ts.map +1 -1
- package/dist/derive-key.js +3 -11
- package/dist/derive-key.mjs +2 -2
- package/dist/derive-password.d.mts +22 -0
- package/dist/derive-password.d.mts.map +1 -0
- package/dist/derive-password.d.ts +22 -0
- package/dist/derive-password.d.ts.map +1 -0
- package/dist/derive-password.js +5 -0
- package/dist/derive-password.mjs +3 -0
- package/dist/deriveKeysFromKey-C4McqO6_.js +47 -0
- package/dist/deriveKeysFromKey-C4McqO6_.js.map +1 -0
- package/dist/deriveKeysFromKey-DPU_h7wr.mjs +35 -0
- package/dist/deriveKeysFromKey-DPU_h7wr.mjs.map +1 -0
- package/dist/{deriveKeysFromPassword-Ko7NxkHM.js → deriveKeysFromPassword-C7xAGGsh.js} +5 -177
- package/dist/deriveKeysFromPassword-C7xAGGsh.js.map +1 -0
- package/dist/{deriveKeysFromPassword-DJRWZ8Rw.mjs → deriveKeysFromPassword-DXgSvTNC.mjs} +7 -131
- package/dist/deriveKeysFromPassword-DXgSvTNC.mjs.map +1 -0
- package/dist/email-crypto.d.mts +24 -46
- package/dist/email-crypto.d.mts.map +1 -1
- package/dist/email-crypto.d.ts +24 -46
- package/dist/email-crypto.d.ts.map +1 -1
- package/dist/email-crypto.js +121 -12
- package/dist/email-crypto.js.map +1 -0
- package/dist/email-crypto.mjs +115 -2
- package/dist/email-crypto.mjs.map +1 -0
- package/dist/email-search.d.mts +18 -18
- package/dist/email-search.d.mts.map +1 -1
- package/dist/email-search.d.ts +18 -18
- package/dist/email-search.d.ts.map +1 -1
- package/dist/email-search.js +25 -597
- package/dist/email-search.mjs +2 -573
- package/dist/{emailEncryptionKey-27mIHh18.mjs → emailEncryptionKey-BtSPYd9M.mjs} +23 -46
- package/dist/emailEncryptionKey-BtSPYd9M.mjs.map +1 -0
- package/dist/{emailEncryptionKey-DbaDAdoW.js → emailEncryptionKey-C4X1Bwy4.js} +22 -45
- package/dist/emailEncryptionKey-C4X1Bwy4.js.map +1 -0
- package/dist/{genID-3Er5IowC.mjs → genID-D08K7JPr.mjs} +4 -40
- package/dist/genID-D08K7JPr.mjs.map +1 -0
- package/dist/{genID-YJSl3YhL.js → genID-cWOPmspk.js} +2 -50
- package/dist/genID-cWOPmspk.js.map +1 -0
- package/dist/hash.d.mts +24 -36
- package/dist/hash.d.mts.map +1 -1
- package/dist/hash.d.ts +24 -36
- package/dist/hash.d.ts.map +1 -1
- package/dist/hash.js +88 -10
- package/dist/hash.js.map +1 -0
- package/dist/hash.mjs +82 -2
- package/dist/hash.mjs.map +1 -0
- package/dist/index.d.mts +17 -16
- package/dist/index.d.mts.map +1 -1
- package/dist/index.d.ts +17 -16
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +60 -83
- package/dist/index.mjs +13 -11
- package/dist/keystore-crypto.d.mts +6 -6
- package/dist/keystore-crypto.d.mts.map +1 -1
- package/dist/keystore-crypto.d.ts +6 -6
- package/dist/keystore-crypto.d.ts.map +1 -1
- package/dist/keystore-crypto.js +1 -1
- package/dist/keystore-crypto.mjs +1 -1
- package/dist/post-quantum-crypto.d.mts +5 -41
- package/dist/post-quantum-crypto.d.mts.map +1 -1
- package/dist/post-quantum-crypto.d.ts +5 -41
- package/dist/post-quantum-crypto.d.ts.map +1 -1
- package/dist/post-quantum-crypto.js +49 -16
- package/dist/post-quantum-crypto.js.map +1 -0
- package/dist/post-quantum-crypto.mjs +46 -2
- package/dist/post-quantum-crypto.mjs.map +1 -0
- package/dist/search-B9YM3XAA.mjs +587 -0
- package/dist/search-B9YM3XAA.mjs.map +1 -0
- package/dist/search-DUTm4-rN.js +731 -0
- package/dist/search-DUTm4-rN.js.map +1 -0
- package/dist/symmetric-crypto.d.mts +13 -42
- package/dist/symmetric-crypto.d.mts.map +1 -1
- package/dist/symmetric-crypto.d.ts +13 -42
- package/dist/symmetric-crypto.d.ts.map +1 -1
- package/dist/symmetric-crypto.js +2 -6
- package/dist/symmetric-crypto.mjs +2 -2
- package/dist/types.d.mts +16 -39
- package/dist/types.d.mts.map +1 -1
- package/dist/types.d.ts +16 -39
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/types.mjs.map +1 -1
- package/dist/utils.d.mts +1 -19
- package/dist/utils.d.mts.map +1 -1
- package/dist/utils.d.ts +1 -19
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -3
- package/dist/utils.mjs +2 -2
- package/dist/xwing-CQmQX6hn.mjs +16 -0
- package/dist/xwing-CQmQX6hn.mjs.map +1 -0
- package/dist/xwing-iRWVRtNE.js +34 -0
- package/dist/xwing-iRWVRtNE.js.map +1 -0
- package/package.json +4 -2
- package/dist/aes-DSDxP8uF.mjs +0 -184
- package/dist/aes-DSDxP8uF.mjs.map +0 -1
- package/dist/aes-bOrKZuUC.js +0 -226
- package/dist/aes-bOrKZuUC.js.map +0 -1
- package/dist/deriveKeysFromPassword-DJRWZ8Rw.mjs.map +0 -1
- package/dist/deriveKeysFromPassword-Ko7NxkHM.js.map +0 -1
- package/dist/email-search.js.map +0 -1
- package/dist/email-search.mjs.map +0 -1
- package/dist/emailEncryptionKey-27mIHh18.mjs.map +0 -1
- package/dist/emailEncryptionKey-DbaDAdoW.js.map +0 -1
- package/dist/emailKeys-BJGdkLrg.js +0 -593
- package/dist/emailKeys-BJGdkLrg.js.map +0 -1
- package/dist/emailKeys-Fp9WR3wl.mjs +0 -509
- package/dist/emailKeys-Fp9WR3wl.mjs.map +0 -1
- package/dist/genID-3Er5IowC.mjs.map +0 -1
- package/dist/genID-YJSl3YhL.js.map +0 -1
- package/dist/keys-BfcaiAOv.mjs +0 -90
- package/dist/keys-BfcaiAOv.mjs.map +0 -1
- package/dist/keys-CinT7kEY.js +0 -125
- package/dist/keys-CinT7kEY.js.map +0 -1
- package/dist/kyber1024-PpwE1rki.mjs +0 -144
- package/dist/kyber1024-PpwE1rki.mjs.map +0 -1
- package/dist/kyber1024-jeKS8CXf.js +0 -173
- package/dist/kyber1024-jeKS8CXf.js.map +0 -1
- package/dist/kyber768-DGBB_RS7.d.ts +0 -32
- package/dist/kyber768-DGBB_RS7.d.ts.map +0 -1
- package/dist/kyber768-DzIcGg1i.d.mts +0 -32
- package/dist/kyber768-DzIcGg1i.d.mts.map +0 -1
- package/dist/mac-BMb1F0dN.js +0 -170
- package/dist/mac-BMb1F0dN.js.map +0 -1
- package/dist/mac-ZpRlx8Fs.mjs +0 -116
- package/dist/mac-ZpRlx8Fs.mjs.map +0 -1
package/dist/email-search.mjs
CHANGED
|
@@ -1,574 +1,3 @@
|
|
|
1
|
-
import {
|
|
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
|
-
|
|
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 {
|
|
2
|
-
import { a as
|
|
3
|
-
import {
|
|
4
|
-
import { n as
|
|
5
|
-
import {
|
|
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
|
|
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
|
|
16
|
-
* @param
|
|
17
|
-
* @param
|
|
18
|
-
* @returns The encrypted keystore
|
|
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
|
-
|
|
30
|
-
|
|
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
|
|
34
|
+
* @param kesytoreOpeningKey - The symmetric key to decrypt the keystore content
|
|
45
35
|
* @param encryptedKeys - The encrypted keystore content
|
|
46
|
-
* @
|
|
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(
|
|
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
|
-
|
|
59
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
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-
|
|
127
|
+
//# sourceMappingURL=emailEncryptionKey-BtSPYd9M.mjs.map
|