@secrecy/lib 1.29.0-feat-rename-file.2 → 1.29.0-feat-upload-file-types.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib/cache.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { LRUCache } from 'lru-cache';
2
2
  import { gigaToBytes } from './utils.js';
3
- export const dataCache = new Map();
3
+ export const filesCache = new Map();
4
4
  export const nodesCache = new Map();
5
5
  export const usersCache = new Map();
6
6
  export const publicKeysCache = new Map();
7
- export const lruCache = new LRUCache({
7
+ export const dataCache = new LRUCache({
8
8
  max: 500,
9
9
  maxSize: gigaToBytes(0.5),
10
10
  sizeCalculation: (value) => {
@@ -82,8 +82,8 @@ export class SecrecyAppClient {
82
82
  async updateSettings(settings) {
83
83
  const updateAppSettings = await this.#apiClient.application.updateSettings.mutate({
84
84
  cloudNodeDaysForDelete: settings.cloudNodeDaysForDelete,
85
- historyDataDaysForDelete: settings.historyDataDaysForDelete,
86
- historyDataMaxCount: settings.historyDataMaxCount,
85
+ historyFileDaysForDelete: settings.historyFileDaysForDelete,
86
+ historyMaxFileCount: settings.historyMaxFileCount,
87
87
  });
88
88
  return updateAppSettings;
89
89
  }
@@ -1,15 +1,15 @@
1
1
  import axios from 'axios';
2
2
  import ky from 'ky';
3
3
  import { encryptName } from '../index.js';
4
- import { nodesCache, dataCache, lruCache } from '../cache.js';
5
- import { secretStreamKeygen } from '../crypto/data.js';
4
+ import { nodesCache, filesCache, dataCache } from '../cache.js';
5
+ import { secretStreamKeygen } from '../crypto/file.js';
6
6
  import { decryptCryptoBox, encryptCryptoBox } from '../crypto/index.js';
7
7
  import { compress, decompress } from '../minify/index.js';
8
8
  import { sodium } from '../sodium.js';
9
9
  import { enumerate, chunks, concatenate } from '../utils/array.js';
10
10
  import { md5 } from '../worker/md5.js';
11
11
  import { decrypt, encrypt } from '../worker/sodium.js';
12
- import { apiDataToExternal } from './convert/data.js';
12
+ import { apiFileToExternal } from './convert/file.js';
13
13
  import { apiNodeFullToInternalFull, apiNodeToExternal, apiNodeToExternalNodeFull, internalNodeFullToNodeFull, } from './convert/node.js';
14
14
  import { promiseAllLimit } from '../utils/promise.js';
15
15
  // import { md5 } from "../worker/index.js";
@@ -23,71 +23,71 @@ export class SecrecyCloudClient {
23
23
  this.#keys = keys;
24
24
  this.#apiClient = apiClient;
25
25
  }
26
- async addDataToHistory({ dataId, nodeId, }) {
27
- const addDataToHistory = await this.#apiClient.cloud.addDataToHistory.mutate({
28
- dataId,
26
+ async addFileToHistory({ fileId, nodeId, }) {
27
+ const addFileToHistory = await this.#apiClient.cloud.addFileToHistory.mutate({
28
+ fileId,
29
29
  nodeId,
30
30
  });
31
- const node = await apiNodeFullToInternalFull(addDataToHistory, this.#keys);
32
- const data = node.history.find((f) => f.id === dataId);
33
- if (data !== undefined) {
31
+ const node = await apiNodeFullToInternalFull(addFileToHistory, this.#keys);
32
+ const file = node.history.find((f) => f.id === fileId);
33
+ if (file !== undefined) {
34
34
  const users = node.users.filter(([u]) => u.id !== this.#client.app.userId);
35
- await this.#apiClient.cloud.shareDataInHistory.mutate({
36
- dataId: data.id,
35
+ await this.#apiClient.cloud.shareFileInHistory.mutate({
36
+ fileId: file.id,
37
37
  nodeId,
38
38
  users: await Promise.all(users.map(async ([u]) => {
39
39
  const userPubKey = await this.#client.app.userPublicKey(u.id);
40
40
  return {
41
41
  id: u.id,
42
- key: sodium.to_hex(encryptCryptoBox(sodium.from_hex(data.key), userPubKey, this.#keys.privateKey)),
42
+ key: sodium.to_hex(encryptCryptoBox(sodium.from_hex(file.key), userPubKey, this.#keys.privateKey)),
43
43
  };
44
44
  })),
45
45
  });
46
46
  }
47
47
  return internalNodeFullToNodeFull(node);
48
48
  }
49
- async uploadData({ data, encryptProgress, uploadProgress, signal, }) {
50
- const dataKey = secretStreamKeygen();
51
- const dataBuffer = data instanceof File ? new Uint8Array(await data.arrayBuffer()) : data;
52
- const compressed = compress(dataBuffer);
53
- const { data: encryptedData, md5: md5Data, md5Encrypted, } = await encrypt(dataKey, compressed, encryptProgress, signal);
54
- const encryptedDataKey = encryptCryptoBox(dataKey, this.#keys.publicKey, this.#keys.privateKey);
55
- const uploadData = await this.#apiClient.cloud.uploadData.mutate({
56
- dataSize: BigInt(encryptedData.byteLength),
57
- dataSizeBefore: BigInt(dataBuffer.byteLength),
58
- dataKey: sodium.to_hex(encryptedDataKey),
49
+ async uploadFile({ file, encryptProgress, uploadProgress, signal, }) {
50
+ const fileKey = secretStreamKeygen();
51
+ const fileBuffer = file instanceof File ? new Uint8Array(await file.arrayBuffer()) : file;
52
+ const compressed = compress(fileBuffer);
53
+ const { data: encryptedFile, md5: md5File, md5Encrypted, } = await encrypt(fileKey, compressed, encryptProgress, signal);
54
+ const encryptedFileKey = encryptCryptoBox(fileKey, this.#keys.publicKey, this.#keys.privateKey);
55
+ const uploadFile = await this.#apiClient.cloud.uploadFile.mutate({
56
+ fileSize: BigInt(encryptedFile.byteLength),
57
+ fileSizeBefore: BigInt(fileBuffer.byteLength),
58
+ fileKey: sodium.to_hex(encryptedFileKey),
59
59
  md5Encrypted,
60
- md5: md5Data,
60
+ md5: md5File,
61
61
  });
62
62
  await uploadProgress?.({
63
- total: encryptedData.byteLength,
63
+ total: encryptedFile.byteLength,
64
64
  current: 0,
65
65
  percent: 0,
66
66
  });
67
- if (uploadData.parts.length === 0) {
67
+ if (uploadFile.parts.length === 0) {
68
68
  await uploadProgress?.({
69
- total: encryptedData.byteLength,
70
- current: encryptedData.byteLength,
69
+ total: encryptedFile.byteLength,
70
+ current: encryptedFile.byteLength,
71
71
  percent: 1,
72
72
  });
73
- return uploadData.dataId;
73
+ return uploadFile.id;
74
74
  }
75
75
  const uploadPartEnded = async (md5, order) => {
76
- const { isUploadPartEnded } = await this.#apiClient.cloud.uploadDataPartEnd.mutate({
77
- dataId: uploadData.dataId,
76
+ const { isUploadPartEnded } = await this.#apiClient.cloud.uploadFilePartEnd.mutate({
77
+ fileId: uploadFile.id,
78
78
  md5,
79
79
  order,
80
80
  });
81
81
  return isUploadPartEnded;
82
82
  };
83
83
  const uploadEnded = async () => {
84
- const { isUploadEnded } = await this.#apiClient.cloud.uploadDataEnd.mutate({
85
- dataId: uploadData.dataId,
84
+ const { isUploadEnded } = await this.#apiClient.cloud.uploadFileEnd.mutate({
85
+ fileId: uploadFile.id,
86
86
  });
87
87
  return isUploadEnded;
88
88
  };
89
89
  const chunkParts = new Array();
90
- for (const [index, chunk] of enumerate(chunks(encryptedData, Number(uploadData.dataPartSize)))) {
90
+ for (const [index, chunk] of enumerate(chunks(encryptedFile, Number(uploadFile.filePartSize)))) {
91
91
  chunkParts.push({
92
92
  order: index + 1,
93
93
  data: chunk,
@@ -99,8 +99,8 @@ export class SecrecyCloudClient {
99
99
  progressParts[part] = progressEvent;
100
100
  const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.loaded, 0);
101
101
  void uploadProgress?.({
102
- percent: current / encryptedData.byteLength,
103
- total: encryptedData.byteLength,
102
+ percent: current / encryptedFile.byteLength,
103
+ total: encryptedFile.byteLength,
104
104
  current,
105
105
  });
106
106
  };
@@ -113,7 +113,7 @@ export class SecrecyCloudClient {
113
113
  for (const [key, value] of Object.entries(part.fields)) {
114
114
  formData.append(key, value);
115
115
  }
116
- formData.append('data', new Blob([chunk.data]), `${uploadData.dataId}-${chunk.order}`);
116
+ formData.append('file', new Blob([chunk.data]), `${uploadFile.id}-${chunk.order}`);
117
117
  await axios.post(part.url, formData, {
118
118
  onUploadProgress: (progressEvent) => {
119
119
  onProgress(part.order, progressEvent);
@@ -122,22 +122,22 @@ export class SecrecyCloudClient {
122
122
  });
123
123
  await uploadPartEnded(chunk.md5, chunk.order);
124
124
  };
125
- await promiseAllLimit(3, uploadData.parts.map((p) => async () => {
125
+ await promiseAllLimit(3, uploadFile.parts.map((p) => async () => {
126
126
  await byPart(p);
127
127
  }));
128
128
  await uploadEnded();
129
- lruCache.set(uploadData.dataId, dataBuffer);
130
- return uploadData.dataId;
129
+ dataCache.set(uploadFile.id, fileBuffer);
130
+ return uploadFile.id;
131
131
  }
132
- async uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, signal, }) {
133
- const dataId = await this.uploadData({
134
- data,
132
+ async uploadFileInCloud({ file, name, nodeId, encryptProgress, uploadProgress, signal, }) {
133
+ const fileId = await this.uploadFile({
134
+ file,
135
135
  encryptProgress,
136
136
  uploadProgress,
137
137
  signal,
138
138
  });
139
139
  return await this.saveInCloud({
140
- dataId,
140
+ fileId,
141
141
  name,
142
142
  nodeId,
143
143
  });
@@ -220,11 +220,11 @@ export class SecrecyCloudClient {
220
220
  });
221
221
  return await apiNodeToExternalNodeFull(node, this.#keys);
222
222
  }
223
- async dataMetadata({ id }) {
224
- const data = await this.#apiClient.cloud.dataById.query({
223
+ async fileMetadata({ id }) {
224
+ const file = await this.#apiClient.cloud.fileById.query({
225
225
  id,
226
226
  });
227
- return apiDataToExternal(data, this.#keys);
227
+ return apiFileToExternal(file, this.#keys);
228
228
  }
229
229
  async shareNode({ nodeId, userId, rights, }) {
230
230
  const publicKey = await this.#client.app.userPublicKey(userId);
@@ -270,26 +270,26 @@ export class SecrecyCloudClient {
270
270
  });
271
271
  return await apiNodeToExternalNodeFull(updateNode, this.#keys);
272
272
  }
273
- async dataContent({ dataId, onDownloadProgress, progressDecrypt, signal, }) {
274
- const cached = lruCache.get(dataId);
273
+ async fileContent({ fileId, onDownloadProgress, progressDecrypt, signal, }) {
274
+ const cached = dataCache.get(fileId);
275
275
  if (cached !== undefined) {
276
276
  return cached;
277
277
  }
278
- const dataContent = await this.#apiClient.cloud.dataContentById.query({
279
- id: dataId,
278
+ const fileContent = await this.#apiClient.cloud.fileContentById.query({
279
+ id: fileId,
280
280
  });
281
281
  const progressParts = {};
282
282
  const onProgress = (part, progressEvent) => {
283
283
  progressParts[part] = progressEvent;
284
284
  const transferredBytes = Object.values(progressParts).reduce((prv, cur) => prv + cur.transferredBytes, 0);
285
- const totalBytes = Number(dataContent.totalSize);
285
+ const totalBytes = Number(fileContent.totalSize);
286
286
  onDownloadProgress?.({
287
287
  percent: transferredBytes / totalBytes,
288
288
  totalBytes,
289
289
  transferredBytes,
290
290
  });
291
291
  };
292
- const encryptedContentFromParts = async (dataParts) => {
292
+ const encryptedContentFromParts = async (fileParts) => {
293
293
  const parts = new Array();
294
294
  const byPart = async (part) => {
295
295
  const buf = new Uint8Array(await ky
@@ -303,14 +303,14 @@ export class SecrecyCloudClient {
303
303
  .arrayBuffer());
304
304
  const md5Part = await md5(buf);
305
305
  if (md5Part !== part.md5) {
306
- throw new Error(`Invalid md5 for part ${part.order} of data ${dataId}`);
306
+ throw new Error(`Invalid md5 for part ${part.order} of file ${fileId}`);
307
307
  }
308
308
  parts.push({
309
309
  data: buf,
310
310
  order: part.order,
311
311
  });
312
312
  };
313
- await promiseAllLimit(3, dataParts.map((p) => async () => {
313
+ await promiseAllLimit(3, fileParts.map((p) => async () => {
314
314
  await byPart(p);
315
315
  }));
316
316
  return concatenate(...parts.sort((a, b) => a.order - b.order).map((p) => p.data));
@@ -318,42 +318,42 @@ export class SecrecyCloudClient {
318
318
  const finalize = async (encryptedContent) => {
319
319
  // const md5Encrypted = await firstValueFrom(md5(of(encryptedContent)));
320
320
  const md5Encrypted = await md5(encryptedContent);
321
- if (md5Encrypted !== dataContent.md5Encrypted) {
321
+ if (md5Encrypted !== fileContent.md5Encrypted) {
322
322
  throw new Error(`Encrypted content does not match`);
323
323
  }
324
- const key = decryptCryptoBox(sodium.from_hex(dataContent.key), dataContent.type === 'received_mail'
325
- ? dataContent.senderPublicKey
326
- : dataContent.type === 'cloud'
327
- ? dataContent.publicKey
324
+ const key = decryptCryptoBox(sodium.from_hex(fileContent.key), fileContent.type === 'received_mail'
325
+ ? fileContent.senderPublicKey
326
+ : fileContent.type === 'cloud'
327
+ ? fileContent.publicKey
328
328
  : this.#keys.publicKey, this.#keys.privateKey);
329
329
  const src = await decrypt(key, encryptedContent, progressDecrypt, signal);
330
330
  // const md5Content = await firstValueFrom(md5(of(src)));
331
331
  const md5Content = await md5(src);
332
- if (md5Content !== dataContent.md5) {
332
+ if (md5Content !== fileContent.md5) {
333
333
  throw new Error(`Content does not match`);
334
334
  }
335
335
  return decompress(src);
336
336
  };
337
- const encryptedContent = dataContent.type === 'lite'
338
- ? dataContent.content
339
- : dataContent.type === 'cloud'
340
- ? await encryptedContentFromParts(dataContent.parts)
337
+ const encryptedContent = fileContent.type === 'lite'
338
+ ? fileContent.content
339
+ : fileContent.type === 'cloud'
340
+ ? await encryptedContentFromParts(fileContent.parts)
341
341
  : // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
342
- dataContent.maybeContent !== null
343
- ? dataContent.maybeContent
344
- : dataContent.maybeParts !== null
345
- ? await encryptedContentFromParts(dataContent.maybeParts)
342
+ fileContent.maybeContent !== null
343
+ ? fileContent.maybeContent
344
+ : fileContent.maybeParts !== null
345
+ ? await encryptedContentFromParts(fileContent.maybeParts)
346
346
  : null;
347
347
  if (encryptedContent === null) {
348
- throw `Can't find content for data ${dataId}`;
348
+ throw `Can't find content for file ${fileId}`;
349
349
  }
350
350
  const data = await finalize(encryptedContent);
351
- lruCache.set(dataId, data);
351
+ dataCache.set(fileId, data);
352
352
  return data;
353
353
  }
354
- async deleteData({ dataId, nodeId, }) {
355
- const { isDeleted } = await this.#apiClient.cloud.deleteData.mutate({
356
- dataId,
354
+ async deleteFile({ fileId, nodeId, }) {
355
+ const { isDeleted } = await this.#apiClient.cloud.deleteFile.mutate({
356
+ fileId,
357
357
  nodeId,
358
358
  });
359
359
  return isDeleted;
@@ -381,7 +381,7 @@ export class SecrecyCloudClient {
381
381
  });
382
382
  return isMoved;
383
383
  }
384
- async saveInCloud({ dataId, name, nodeId, }) {
384
+ async saveInCloud({ fileId, name, nodeId, }) {
385
385
  if (nodeId !== undefined && !nodesCache.has(nodeId)) {
386
386
  await this.node({ id: nodeId });
387
387
  if (!nodesCache.has(nodeId)) {
@@ -394,50 +394,50 @@ export class SecrecyCloudClient {
394
394
  }
395
395
  }
396
396
  let key = '';
397
- const data = dataCache.get(dataId);
398
- if (data === undefined) {
399
- await this.dataMetadata({ id: dataId });
400
- const data = dataCache.get(dataId);
401
- if (data === undefined) {
397
+ const file = filesCache.get(fileId);
398
+ if (file === undefined) {
399
+ await this.fileMetadata({ id: fileId });
400
+ const file = filesCache.get(fileId);
401
+ if (file === undefined) {
402
402
  const receivedMails = await this.#client.mail.receivedMails();
403
- const mail = receivedMails.find((m) => m.data.some((f) => f.id === dataId));
403
+ const mail = receivedMails.find((m) => m.files.some((f) => f.id === fileId));
404
404
  if (mail === undefined) {
405
405
  const err = {
406
406
  name: 'ClientError',
407
407
  code: 'NOT_FOUND',
408
- message: `Can't find mail with the data ${dataId}`,
408
+ message: `Can't find mail with the file ${fileId}`,
409
409
  };
410
410
  throw err;
411
411
  }
412
- const dataMail = mail.data.find((f) => f.id === dataId);
413
- if (dataMail === undefined) {
412
+ const fileMail = mail.files.find((f) => f.id === fileId);
413
+ if (fileMail === undefined) {
414
414
  const err = {
415
415
  name: 'ClientError',
416
416
  code: 'NOT_FOUND',
417
- message: `Can't find mail with the data ${dataId}`,
417
+ message: `Can't find mail with the file ${fileId}`,
418
418
  };
419
419
  throw err;
420
420
  }
421
421
  const senderPubKey = await this.#client.app.userPublicKey(mail.sender.id);
422
- const dataKey = decryptCryptoBox(sodium.from_hex(dataMail.key), senderPubKey, this.#keys.privateKey);
423
- key = sodium.to_hex(dataKey);
422
+ const fileKey = decryptCryptoBox(sodium.from_hex(fileMail.key), senderPubKey, this.#keys.privateKey);
423
+ key = sodium.to_hex(fileKey);
424
424
  }
425
425
  else {
426
- key = data.key;
426
+ key = file.key;
427
427
  }
428
428
  }
429
429
  else {
430
- key = data.key;
430
+ key = file.key;
431
431
  }
432
432
  key = sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), this.#keys.publicKey, this.#keys.privateKey));
433
433
  const nameKey = secretStreamKeygen();
434
434
  const encryptedName = await encryptName(name, sodium.to_hex(nameKey));
435
435
  const encryptedNameKey = sodium.to_hex(encryptCryptoBox(nameKey, this.#keys.publicKey, this.#keys.privateKey));
436
436
  const saveInCloud = await this.#apiClient.cloud.saveInCloud.mutate({
437
- dataId,
437
+ fileId,
438
438
  key,
439
439
  nodeId: nodeId ?? null,
440
- dataName: encryptedName,
440
+ filename: encryptedName,
441
441
  nameKey: encryptedNameKey,
442
442
  });
443
443
  const node = await apiNodeToExternalNodeFull(saveInCloud, this.#keys);
@@ -468,7 +468,7 @@ export class SecrecyCloudClient {
468
468
  nameKey: nameKey !== null
469
469
  ? sodium.to_hex(encryptCryptoBox(sodium.from_hex(nameKey), publicKey, this.#keys.privateKey))
470
470
  : null,
471
- data: 'history' in node
471
+ files: 'history' in node
472
472
  ? node.history.map((f) => ({
473
473
  id: f.id,
474
474
  key: sodium.to_hex(encryptCryptoBox(sodium.from_hex(f.key), publicKey, this.#keys.privateKey)),
@@ -1,4 +1,4 @@
1
- import { dataCache } from '../cache.js';
1
+ import { filesCache } from '../cache.js';
2
2
  import { encryptCryptoBox, sodium } from '../index.js';
3
3
  import { convertInternalMailToExternal } from './convert/mail.js';
4
4
  export class SecrecyMailClient {
@@ -67,11 +67,11 @@ export class SecrecyMailClient {
67
67
  }
68
68
  if (senderFiles !== undefined) {
69
69
  for (const f of senderFiles) {
70
- let data = dataCache.get(f.id);
71
- if (data === undefined) {
72
- await this.#client.cloud.dataMetadata({ id: f.id });
73
- data = dataCache.get(f.id);
74
- if (data === undefined) {
70
+ let file = filesCache.get(f.id);
71
+ if (file === undefined) {
72
+ await this.#client.cloud.fileMetadata({ id: f.id });
73
+ file = filesCache.get(f.id);
74
+ if (file === undefined) {
75
75
  throw new Error(`File ${f.name} (${f.id}) does not exists`);
76
76
  }
77
77
  }
@@ -132,7 +132,7 @@ export class SecrecyMailClient {
132
132
  if (email === undefined) {
133
133
  continue;
134
134
  }
135
- const input = await this._eachUser(draft.data, draft.subject, draft.body, email);
135
+ const input = await this._eachUser(draft.files, draft.subject, draft.body, email);
136
136
  if (input === null) {
137
137
  temporaryRecipients.push(email);
138
138
  }
@@ -141,7 +141,7 @@ export class SecrecyMailClient {
141
141
  }
142
142
  }
143
143
  for (const { id } of draft.recipients) {
144
- const input = await this._eachUser(draft.data, draft.subject, draft.body, id);
144
+ const input = await this._eachUser(draft.files, draft.subject, draft.body, id);
145
145
  if (input === null) {
146
146
  temporaryRecipients.push(id);
147
147
  }
@@ -167,7 +167,7 @@ export class SecrecyMailClient {
167
167
  continue;
168
168
  }
169
169
  try {
170
- const input = await this._eachUser(mail.data, mail.subject, mail.body, email);
170
+ const input = await this._eachUser(mail.files, mail.subject, mail.body, email);
171
171
  if (input === null) {
172
172
  continue;
173
173
  }
@@ -186,16 +186,16 @@ export class SecrecyMailClient {
186
186
  const hashKey = sodium.randombytes_buf(sodium.crypto_generichash_KEYBYTES, 'hex');
187
187
  const hash = sodium.crypto_generichash(sodium.crypto_generichash_BYTES, JSON.stringify({ body, subject }), hashKey, 'hex');
188
188
  for (const f of senderFiles) {
189
- let data = dataCache.get(f.id);
190
- if (data === undefined) {
191
- await this.#client.cloud.dataMetadata({ id: f.id });
192
- data = dataCache.get(f.id);
193
- if (data === undefined) {
189
+ let file = filesCache.get(f.id);
190
+ if (file === undefined) {
191
+ await this.#client.cloud.fileMetadata({ id: f.id });
192
+ file = filesCache.get(f.id);
193
+ if (file === undefined) {
194
194
  throw new Error(`File ${f.name} (${f.id}) does not exists`);
195
195
  }
196
196
  }
197
197
  senderFiles.push({
198
- id: data.id,
198
+ id: file.id,
199
199
  name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#keys.publicKey, this.#keys.privateKey)),
200
200
  });
201
201
  }
@@ -254,25 +254,25 @@ export class SecrecyMailClient {
254
254
  const unreadReceivedMailsCount = await this.#apiClient.mail.unreadReceivedCount.query({});
255
255
  return unreadReceivedMailsCount;
256
256
  }
257
- _eachUser = async (data, subject, body, idOrMail) => {
257
+ _eachUser = async (files, subject, body, idOrMail) => {
258
258
  // const pubKey = await this.#client.app.userPublicKey(userId)
259
259
  const pubKey = await this.#client.app.userPublicKey(idOrMail);
260
260
  // const recipientsFiles = new Array<MailFileInput>()
261
261
  const recipientsFiles = new Array();
262
- for (const f of data) {
263
- let dataInHistory = dataCache.get(f.id);
264
- if (dataInHistory === undefined) {
265
- await this.#client.cloud.dataMetadata({ id: f.id });
266
- dataInHistory = dataCache.get(f.id);
267
- if (dataInHistory === undefined) {
262
+ for (const f of files) {
263
+ let fileInHistory = filesCache.get(f.id);
264
+ if (fileInHistory === undefined) {
265
+ await this.#client.cloud.fileMetadata({ id: f.id });
266
+ fileInHistory = filesCache.get(f.id);
267
+ if (fileInHistory === undefined) {
268
268
  throw new Error(`File ${f.name} (${f.id}) does not exists`);
269
269
  }
270
270
  }
271
- const key = dataInHistory.key;
271
+ const key = fileInHistory.key;
272
272
  recipientsFiles.push({
273
273
  id: f.id,
274
274
  name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), pubKey, this.#keys.privateKey)),
275
- dataKey: sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#keys.privateKey)),
275
+ fileKey: sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#keys.privateKey)),
276
276
  });
277
277
  }
278
278
  return {
@@ -280,7 +280,7 @@ export class SecrecyMailClient {
280
280
  recipientId: idOrMail,
281
281
  body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), pubKey, this.#keys.privateKey)),
282
282
  subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), pubKey, this.#keys.privateKey)),
283
- data: recipientsFiles,
283
+ files: recipientsFiles,
284
284
  };
285
285
  };
286
286
  }
@@ -0,0 +1,29 @@
1
+ import { filesCache } from '../../cache.js';
2
+ import { decryptCryptoBox } from '../../crypto/index.js';
3
+ import { sodium } from '../../sodium.js';
4
+ export function apiFileToInternal(apiFile, keyPair) {
5
+ const file = {
6
+ id: apiFile.id,
7
+ md5: apiFile.md5,
8
+ md5Encrypted: apiFile.md5Encrypted,
9
+ createdAt: apiFile.createdAt,
10
+ size: apiFile.size,
11
+ sizeBefore: apiFile.sizeBefore,
12
+ key: sodium.to_hex(decryptCryptoBox(sodium.from_hex(apiFile.access.key), apiFile.access.sharedByPubKey, keyPair.privateKey)),
13
+ };
14
+ filesCache.set(file.id, file);
15
+ return file;
16
+ }
17
+ export function internalFileToFile(internal) {
18
+ return {
19
+ id: internal.id,
20
+ md5: internal.md5,
21
+ md5Encrypted: internal.md5Encrypted,
22
+ createdAt: internal.createdAt,
23
+ size: internal.size,
24
+ sizeBefore: internal.sizeBefore,
25
+ };
26
+ }
27
+ export function apiFileToExternal(apiFile, keyPair) {
28
+ return internalFileToFile(apiFileToInternal(apiFile, keyPair));
29
+ }
@@ -30,12 +30,12 @@ export async function convertInternalMailToExternal({ client, mail, keyPair, })
30
30
  temporaryRecipients: [], // TODO
31
31
  recipients: mI.recipients,
32
32
  sender: mail.sender,
33
- data: mail.data.map((f) => {
34
- const name = sodium.to_string(decryptCryptoBox(sodium.from_hex(f.dataName), pubKey, privateKey));
33
+ files: mail.files.map((f) => {
34
+ const name = sodium.to_string(decryptCryptoBox(sodium.from_hex(f.filename), pubKey, privateKey));
35
35
  return {
36
- id: f.dataId,
36
+ id: f.fileId,
37
37
  name,
38
- key: f.dataKey,
38
+ key: f.fileKey,
39
39
  };
40
40
  }),
41
41
  };
@@ -1,8 +1,8 @@
1
1
  import { sodium } from '../../sodium.js';
2
2
  import { decryptCryptoBox } from '../../crypto/index.js';
3
3
  import { nodesCache } from '../../cache.js';
4
- import { decryptSecretStream } from '../../crypto/data.js';
5
- import { apiDataToInternal, internalDataToExternalData } from './data.js';
4
+ import { decryptSecretStream } from '../../crypto/file.js';
5
+ import { apiFileToInternal, internalFileToFile } from './file.js';
6
6
  export async function apiNodeToInternal(apiNode, keyPair) {
7
7
  const internal = {
8
8
  id: apiNode.id,
@@ -23,7 +23,7 @@ export async function apiNodeToInternal(apiNode, keyPair) {
23
23
  deletedAt: apiNode.deletedAt,
24
24
  users: apiNode.users,
25
25
  parentId: apiNode.parentId ?? null,
26
- currentDataId: apiNode.currentDataId ?? null,
26
+ currentFileId: apiNode.currentFileId ?? null,
27
27
  };
28
28
  internal.access = { ...apiNode.access };
29
29
  if (apiNode.access.nameKey !== null) {
@@ -47,13 +47,13 @@ export async function apiNodeFullToInternalFull(apiNodeFull, keyPair) {
47
47
  return {
48
48
  ...f,
49
49
  current: apiNodeFull.current !== null
50
- ? apiDataToInternal(apiNodeFull.current, keyPair)
50
+ ? apiFileToInternal(apiNodeFull.current, keyPair)
51
51
  : undefined,
52
52
  parent: apiNodeFull.parent !== null
53
53
  ? await apiNodeToInternal(apiNodeFull.parent, keyPair)
54
54
  : null,
55
55
  children: await Promise.all(apiNodeFull.children.map(async (s) => await apiNodeToInternal(s, keyPair))),
56
- history: apiNodeFull.history.map((f) => apiDataToInternal(f, keyPair)),
56
+ history: apiNodeFull.history.map((f) => apiFileToInternal(f, keyPair)),
57
57
  };
58
58
  }
59
59
  export function internalNodeToNode(internal) {
@@ -76,9 +76,9 @@ export function internalNodeFullToNodeFull(internal) {
76
76
  ...internalNodeToNode(internal),
77
77
  parent: internal.parent !== null ? internalNodeToNode(internal.parent) : null,
78
78
  children: internal.children.map(internalNodeToNode),
79
- history: internal.history.map((f) => internalDataToExternalData(f)),
79
+ history: internal.history.map((f) => internalFileToFile(f)),
80
80
  current: internal.current !== null && internal.current !== undefined
81
- ? internalDataToExternalData(internal.current)
81
+ ? internalFileToFile(internal.current)
82
82
  : undefined,
83
83
  };
84
84
  }
@@ -1,10 +1,10 @@
1
1
  import { BaseClient } from '../base-client.js';
2
- import { encryptSecretStream } from '../crypto/data.js';
2
+ import { encryptSecretStream } from '../crypto/file.js';
3
3
  import { sodium } from '../sodium.js';
4
4
  import { SecrecyCloudClient } from './SecrecyCloudClient.js';
5
5
  import { SecrecyMailClient } from './SecrecyMailClient.js';
6
6
  import { SecrecyAppClient } from './SecrecyAppClient.js';
7
- import { nodesCache, dataCache, publicKeysCache } from '../cache.js';
7
+ import { nodesCache, filesCache, publicKeysCache } from '../cache.js';
8
8
  import { SecrecyDbClient } from './SecrecyDbClient.js';
9
9
  import { SecrecyWalletClient } from './SecrecyWalletClient.js';
10
10
  import { SecrecyPayClient } from './SecrecyPayClient.js';
@@ -53,7 +53,7 @@ export class SecrecyClient extends BaseClient {
53
53
  }
54
54
  async logout(sessionId) {
55
55
  nodesCache.clear();
56
- dataCache.clear();
56
+ filesCache.clear();
57
57
  publicKeysCache.clear();
58
58
  await super.logout(sessionId);
59
59
  }