@secrecy/lib 1.29.0-feat-rename-file.3 → 1.29.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/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) => {
@@ -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";
@@ -29,7 +29,7 @@ export class SecrecyCloudClient {
29
29
  nodeId,
30
30
  });
31
31
  const node = await apiNodeFullToInternalFull(addDataToHistory, this.#keys);
32
- const data = node.history.find((f) => f.id === dataId);
32
+ const data = node.history.find((d) => d.id === dataId);
33
33
  if (data !== undefined) {
34
34
  const users = node.users.filter(([u]) => u.id !== this.#client.app.userId);
35
35
  await this.#apiClient.cloud.shareDataInHistory.mutate({
@@ -46,33 +46,33 @@ export class SecrecyCloudClient {
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);
49
+ async uploadData({ 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
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),
56
+ dataSize: BigInt(encryptedFile.byteLength),
57
+ dataSizeBefore: BigInt(fileBuffer.byteLength),
58
+ dataKey: 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
67
  if (uploadData.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
73
  return uploadData.dataId;
74
74
  }
75
- const uploadPartEnded = async (md5, order) => {
75
+ const uploadDataPartEnd = async (md5, order) => {
76
76
  const { isUploadPartEnded } = await this.#apiClient.cloud.uploadDataPartEnd.mutate({
77
77
  dataId: uploadData.dataId,
78
78
  md5,
@@ -87,7 +87,7 @@ export class SecrecyCloudClient {
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(uploadData.dataPartSize)))) {
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,25 +113,25 @@ 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]), `${uploadData.dataId}-${chunk.order}`);
117
117
  await axios.post(part.url, formData, {
118
118
  onUploadProgress: (progressEvent) => {
119
119
  onProgress(part.order, progressEvent);
120
120
  },
121
121
  signal,
122
122
  });
123
- await uploadPartEnded(chunk.md5, chunk.order);
123
+ await uploadDataPartEnd(chunk.md5, chunk.order);
124
124
  };
125
125
  await promiseAllLimit(3, uploadData.parts.map((p) => async () => {
126
126
  await byPart(p);
127
127
  }));
128
128
  await uploadEnded();
129
- lruCache.set(uploadData.dataId, dataBuffer);
129
+ dataCache.set(uploadData.dataId, fileBuffer);
130
130
  return uploadData.dataId;
131
131
  }
132
- async uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, signal, }) {
132
+ async uploadDataInCloud({ file, name, nodeId, encryptProgress, uploadProgress, signal, }) {
133
133
  const dataId = await this.uploadData({
134
- data,
134
+ file,
135
135
  encryptProgress,
136
136
  uploadProgress,
137
137
  signal,
@@ -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.dataById.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.dataContentById.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,40 +318,40 @@ 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
- const data = await finalize(encryptedContent);
351
- lruCache.set(dataId, data);
350
+ const data = await finalize(new Uint8Array(encryptedContent));
351
+ dataCache.set(fileId, data);
352
352
  return data;
353
353
  }
354
- async deleteData({ dataId, nodeId, }) {
354
+ async deleteFile({ dataId, nodeId, }) {
355
355
  const { isDeleted } = await this.#apiClient.cloud.deleteData.mutate({
356
356
  dataId,
357
357
  nodeId,
@@ -394,40 +394,40 @@ 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(dataId);
398
+ if (file === undefined) {
399
+ await this.fileMetadata({ id: dataId });
400
+ const file = filesCache.get(dataId);
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 === dataId));
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 ${dataId}`,
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 === dataId);
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 ${dataId}`,
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();
@@ -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
  }
@@ -175,11 +175,13 @@ export class SecrecyMailClient {
175
175
  id: mail.mailIntegrityId,
176
176
  recipient: {
177
177
  ...input,
178
- attachments: input.attachments.map((attachment) => ({
179
- id: attachment.dataId,
180
- key: attachment.key,
181
- name: attachment.name,
182
- })),
178
+ attachments: input.attachments.map(({ dataId, key, name }) => {
179
+ return {
180
+ id: dataId,
181
+ key,
182
+ name,
183
+ };
184
+ }),
183
185
  },
184
186
  });
185
187
  }
@@ -193,16 +195,16 @@ export class SecrecyMailClient {
193
195
  const hashKey = sodium.randombytes_buf(sodium.crypto_generichash_KEYBYTES, 'hex');
194
196
  const hash = sodium.crypto_generichash(sodium.crypto_generichash_BYTES, JSON.stringify({ body, subject }), hashKey, 'hex');
195
197
  for (const f of senderFiles) {
196
- let data = dataCache.get(f.id);
197
- if (data === undefined) {
198
- await this.#client.cloud.dataMetadata({ id: f.id });
199
- data = dataCache.get(f.id);
200
- if (data === undefined) {
198
+ let file = filesCache.get(f.id);
199
+ if (file === undefined) {
200
+ await this.#client.cloud.fileMetadata({ id: f.id });
201
+ file = filesCache.get(f.id);
202
+ if (file === undefined) {
201
203
  throw new Error(`File ${f.name} (${f.id}) does not exists`);
202
204
  }
203
205
  }
204
206
  senderFiles.push({
205
- id: data.id,
207
+ id: file.id,
206
208
  name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#keys.publicKey, this.#keys.privateKey)),
207
209
  });
208
210
  }
@@ -261,25 +263,25 @@ export class SecrecyMailClient {
261
263
  const unreadReceivedMailsCount = await this.#apiClient.mail.unreadReceivedCount.query({});
262
264
  return unreadReceivedMailsCount;
263
265
  }
264
- _eachUser = async (data, subject, body, idOrMail) => {
266
+ _eachUser = async (files, subject, body, idOrMail) => {
265
267
  // const pubKey = await this.#client.app.userPublicKey(userId)
266
268
  const pubKey = await this.#client.app.userPublicKey(idOrMail);
267
- // const attachments = new Array<MailFileInput>()
268
- const attachments = new Array();
269
- for (const f of data) {
270
- let dataInHistory = dataCache.get(f.id);
271
- if (dataInHistory === undefined) {
272
- await this.#client.cloud.dataMetadata({ id: f.id });
273
- dataInHistory = dataCache.get(f.id);
274
- if (dataInHistory === undefined) {
269
+ // const recipientsFiles = new Array<MailFileInput>()
270
+ const recipientsFiles = new Array();
271
+ for (const f of files) {
272
+ let fileInHistory = filesCache.get(f.id);
273
+ if (fileInHistory === undefined) {
274
+ await this.#client.cloud.fileMetadata({ id: f.id });
275
+ fileInHistory = filesCache.get(f.id);
276
+ if (fileInHistory === undefined) {
275
277
  throw new Error(`File ${f.name} (${f.id}) does not exists`);
276
278
  }
277
279
  }
278
- const key = dataInHistory.key;
279
- attachments.push({
280
+ const key = fileInHistory.key;
281
+ recipientsFiles.push({
280
282
  id: f.id,
281
283
  name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), pubKey, this.#keys.privateKey)),
282
- dataKey: sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#keys.privateKey)),
284
+ key: sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#keys.privateKey)),
283
285
  });
284
286
  }
285
287
  return {
@@ -287,7 +289,7 @@ export class SecrecyMailClient {
287
289
  recipientId: idOrMail,
288
290
  body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), pubKey, this.#keys.privateKey)),
289
291
  subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), pubKey, this.#keys.privateKey)),
290
- attachments,
292
+ attachments: recipientsFiles,
291
293
  };
292
294
  };
293
295
  }
@@ -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.attachments.map((f) => {
34
- const name = sodium.to_string(decryptCryptoBox(sodium.from_hex(f.name), pubKey, privateKey));
33
+ files: mail.attachments.map((attachment) => {
34
+ const name = sodium.to_string(decryptCryptoBox(sodium.from_hex(attachment.name), pubKey, privateKey));
35
35
  return {
36
- id: f.dataId,
36
+ id: attachment.dataId,
37
37
  name,
38
- key: f.key,
38
+ key: attachment.key,
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.currentDataId ?? 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
  }
@@ -1,6 +1,6 @@
1
- import type { InternalNode, InternalData, InternalNodeFull } from './client/types/index.js';
1
+ import type { InternalNode, InternalFile, InternalNodeFull } from './client/types/index.js';
2
2
  import { LRUCache } from 'lru-cache';
3
- export declare const dataCache: Map<string, InternalData>;
3
+ export declare const filesCache: Map<string, InternalFile>;
4
4
  export declare const nodesCache: Map<string, InternalNode | InternalNodeFull>;
5
5
  export declare const usersCache: Map<string, {
6
6
  id: string;
@@ -10,4 +10,4 @@ export declare const usersCache: Map<string, {
10
10
  isSearchable: boolean;
11
11
  }>;
12
12
  export declare const publicKeysCache: Map<string, string>;
13
- export declare const lruCache: LRUCache<string, Uint8Array, unknown>;
13
+ export declare const dataCache: LRUCache<string, Uint8Array, unknown>;
@@ -1,5 +1,5 @@
1
1
  import type { ProgressCallback, SecrecyClient } from '../index.js';
2
- import type { DataMetadata, KeyPair, Node, NodeFull, NodeType, Rights } from './types/index.js';
2
+ import type { FileMetadata, KeyPair, Node, NodeFull, NodeType, Rights } from './types/index.js';
3
3
  import { type ApiClient } from '../client.js';
4
4
  import { type DownloadProgress } from '../types.js';
5
5
  export declare class SecrecyCloudClient {
@@ -9,14 +9,14 @@ export declare class SecrecyCloudClient {
9
9
  dataId: string;
10
10
  nodeId: string;
11
11
  }): Promise<NodeFull>;
12
- uploadData({ data, encryptProgress, uploadProgress, signal, }: {
13
- data: globalThis.File | Uint8Array;
12
+ uploadData({ file, encryptProgress, uploadProgress, signal, }: {
13
+ file: globalThis.File | Uint8Array;
14
14
  encryptProgress?: ProgressCallback;
15
15
  uploadProgress?: ProgressCallback;
16
16
  signal?: AbortSignal;
17
17
  }): Promise<string>;
18
- uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, signal, }: {
19
- data: globalThis.File | Uint8Array;
18
+ uploadDataInCloud({ file, name, nodeId, encryptProgress, uploadProgress, signal, }: {
19
+ file: globalThis.File | Uint8Array;
20
20
  name: string;
21
21
  nodeId?: string;
22
22
  encryptProgress?: ProgressCallback;
@@ -46,9 +46,9 @@ export declare class SecrecyCloudClient {
46
46
  id?: string | null | undefined;
47
47
  deleted?: boolean | null | undefined;
48
48
  }): Promise<NodeFull>;
49
- dataMetadata({ id }: {
49
+ fileMetadata({ id }: {
50
50
  id: string;
51
- }): Promise<DataMetadata>;
51
+ }): Promise<FileMetadata>;
52
52
  shareNode({ nodeId, userId, rights, }: {
53
53
  nodeId: string;
54
54
  userId: string;
@@ -60,13 +60,13 @@ export declare class SecrecyCloudClient {
60
60
  isFavorite?: boolean | null | undefined;
61
61
  deletedAt?: Date | null | undefined;
62
62
  }): Promise<NodeFull>;
63
- dataContent({ dataId, onDownloadProgress, progressDecrypt, signal, }: {
64
- dataId: string;
63
+ fileContent({ fileId, onDownloadProgress, progressDecrypt, signal, }: {
64
+ fileId: string;
65
65
  onDownloadProgress?: (progress: DownloadProgress) => void;
66
66
  progressDecrypt?: ProgressCallback;
67
67
  signal?: AbortSignal;
68
68
  }): Promise<Uint8Array>;
69
- deleteData({ dataId, nodeId, }: {
69
+ deleteFile({ dataId, nodeId, }: {
70
70
  dataId: string;
71
71
  nodeId: string;
72
72
  }): Promise<boolean>;
@@ -0,0 +1,4 @@
1
+ import type { ApiFile, InternalFile, FileMetadata, KeyPair } from '../types/index.js';
2
+ export declare function apiFileToInternal(apiFile: ApiFile, keyPair: KeyPair): InternalFile;
3
+ export declare function internalFileToFile(internal: InternalFile): FileMetadata;
4
+ export declare function apiFileToExternal(apiFile: ApiFile, keyPair: KeyPair): FileMetadata;
@@ -1,5 +1,5 @@
1
1
  import { BaseClient } from '../base-client.js';
2
- import type { Progress } from '../crypto/data.js';
2
+ import type { Progress } from '../crypto/file.js';
3
3
  import { SecrecyCloudClient } from './SecrecyCloudClient.js';
4
4
  import { SecrecyMailClient } from './SecrecyMailClient.js';
5
5
  import { SecrecyAppClient } from './SecrecyAppClient.js';
@@ -0,0 +1,6 @@
1
+ import { type RouterOutputs } from '../../client.js';
2
+ export type FileMetadata = Pick<ApiFile, 'id' | 'size' | 'sizeBefore' | 'md5' | 'md5Encrypted' | 'createdAt'>;
3
+ export type InternalFile = FileMetadata & {
4
+ key: string;
5
+ };
6
+ export type ApiFile = NonNullable<RouterOutputs['cloud']['dataById']>;
@@ -1,6 +1,6 @@
1
1
  import { z } from 'zod';
2
2
  export type * from './app.js';
3
- export type * from './data.js';
3
+ export type * from './file.js';
4
4
  export type * from './node.js';
5
5
  export type * from './mail.js';
6
6
  export type * from './user.js';
@@ -15,7 +15,7 @@ export interface BaseMail {
15
15
  isAltered: boolean;
16
16
  recipients: Array<Omit<PublicUser, 'publicKey'>>;
17
17
  temporaryRecipients: TemporaryMailUser[];
18
- data: Array<{
18
+ files: Array<{
19
19
  id: string;
20
20
  name: string;
21
21
  key: string;
@@ -74,10 +74,10 @@ export interface WaitingReceivedMail {
74
74
  recipients: PublicUser[];
75
75
  temporaryRecipients: TemporaryMailUser[];
76
76
  }
77
- export interface MailData {
78
- dataKey: string;
79
- dataName: string;
80
- data: {
77
+ export interface MailFile {
78
+ fileKey: string;
79
+ filename: string;
80
+ file: {
81
81
  id: string;
82
82
  };
83
83
  }
@@ -1,5 +1,5 @@
1
1
  import { type RouterOutputs } from '../../client.js';
2
- import type { DataMetadata, InternalData, PublicUser } from './index.js';
2
+ import type { FileMetadata, InternalFile, PublicUser } from './index.js';
3
3
  export type Rights = ApiNode['users'][number][1];
4
4
  export type NodeAccess<T extends Record<string, unknown> = Record<string, unknown>> = T & {
5
5
  rights: Rights;
@@ -34,17 +34,17 @@ export interface Node<T extends NodeBreadcrumbItem = NodeBreadcrumbItem, U exten
34
34
  createdBy: PublicUser;
35
35
  access: NodeAccess<U>;
36
36
  users: Array<[PublicUser, Rights]>;
37
- currentDataId: string | null;
37
+ currentFileId: string | null;
38
38
  parentId: string | null;
39
39
  }
40
- export type NodeFull<T extends NodeBreadcrumbItem = NodeBreadcrumbItem, U extends Record<string, unknown> = Record<string, unknown>, V extends DataMetadata = DataMetadata> = Node<T, U> & {
40
+ export type NodeFull<T extends NodeBreadcrumbItem = NodeBreadcrumbItem, U extends Record<string, unknown> = Record<string, unknown>, V extends FileMetadata = FileMetadata> = Node<T, U> & {
41
41
  parent: Node<T, U> | null;
42
42
  children: Array<Node<T, U>>;
43
43
  current?: V;
44
44
  history: V[];
45
45
  };
46
46
  export type InternalNode = Node<InternalNodeBreadcrumbItem, NameKey>;
47
- export type InternalNodeFull = NodeFull<InternalNodeBreadcrumbItem, NameKey, InternalData>;
47
+ export type InternalNodeFull = NodeFull<InternalNodeBreadcrumbItem, NameKey, InternalFile>;
48
48
  export type ApiNode = RouterOutputs['cloud']['nodeById'];
49
49
  export type ApiNodeFull = RouterOutputs['cloud']['nodeFullById'];
50
50
  export type ApiNodeParent = NonNullable<RouterOutputs['cloud']['nodeFullById']['parent']>;
@@ -1,8 +1,8 @@
1
1
  export * from './client/index.js';
2
2
  export * from './crypto/index.js';
3
- export type { Progress } from './crypto/data.js';
3
+ export type { Progress } from './crypto/file.js';
4
4
  export { BaseClient } from './base-client.js';
5
- export type { Node, NodeFull, DataMetadata, SecrecyUserApp, BaseMail, ReceivedMail, SentMail, PublicUser, SelfUser, NodeSize, MailData, MailIntegrity, DraftMail, Mail, WaitingReceivedMail, KeyPair, } from './client/types/index.js';
5
+ export type { Node, NodeFull, FileMetadata, SecrecyUserApp, BaseMail, ReceivedMail, SentMail, PublicUser, SelfUser, NodeSize, MailFile, MailIntegrity, DraftMail, Mail, WaitingReceivedMail, KeyPair, } from './client/types/index.js';
6
6
  export * from './client/helpers.js';
7
7
  export * from './sodium.js';
8
8
  export * from './utils/store-buddy.js';
@@ -1,3 +1,3 @@
1
- import type { EncryptedFile, Progress } from '../crypto/data.js';
1
+ import type { EncryptedFile, Progress } from '../crypto/file.js';
2
2
  export declare function encrypt(key: Uint8Array, dataToEncrypt: Uint8Array, progress?: (progress: Progress) => Promise<void>, signal?: AbortSignal): Promise<EncryptedFile>;
3
3
  export declare function decrypt(key: Uint8Array, dataToDecrypt: Uint8Array, progress?: (progress: Progress) => Promise<void>, signal?: AbortSignal): Promise<Uint8Array>;
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@secrecy/lib",
3
3
  "author": "Anonymize <anonymize@gmail.com>",
4
4
  "description": "Anonymize Secrecy Library",
5
- "version": "1.29.0-feat-rename-file.3",
5
+ "version": "1.29.0",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/anonymize-org/lib.git"
@@ -74,7 +74,7 @@
74
74
  },
75
75
  "dependencies": {
76
76
  "@secrecy/lib-utils": "^1.0.18",
77
- "@secrecy/trpc-api-types": "1.27.0-feat-rename-file.12",
77
+ "@secrecy/trpc-api-types": "1.27.0-feat-rename-file.11",
78
78
  "@trpc/client": "10.45.2",
79
79
  "@trpc/server": "10.45.2",
80
80
  "@types/libsodium-wrappers-sumo": "^0.7.8",
@@ -1,29 +0,0 @@
1
- import { dataCache } from '../../cache.js';
2
- import { decryptCryptoBox } from '../../crypto/index.js';
3
- import { sodium } from '../../sodium.js';
4
- export function apiDataToInternal(apiData, keyPair) {
5
- const data = {
6
- id: apiData.id,
7
- md5: apiData.md5,
8
- md5Encrypted: apiData.md5Encrypted,
9
- createdAt: apiData.createdAt,
10
- size: apiData.size,
11
- sizeBefore: apiData.sizeBefore,
12
- key: sodium.to_hex(decryptCryptoBox(sodium.from_hex(apiData.access.key), apiData.access.sharedByPubKey, keyPair.privateKey)),
13
- };
14
- dataCache.set(data.id, data);
15
- return data;
16
- }
17
- export function internalDataToExternalData(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 apiDataToExternal(apiData, keyPair) {
28
- return internalDataToExternalData(apiDataToInternal(apiData, keyPair));
29
- }
@@ -1,4 +0,0 @@
1
- import type { ApiData, InternalData, DataMetadata, KeyPair } from '../types/index.js';
2
- export declare function apiDataToInternal(apiData: ApiData, keyPair: KeyPair): InternalData;
3
- export declare function internalDataToExternalData(internal: InternalData): DataMetadata;
4
- export declare function apiDataToExternal(apiData: ApiData, keyPair: KeyPair): DataMetadata;
@@ -1,6 +0,0 @@
1
- import { type RouterOutputs } from '../../client.js';
2
- export type DataMetadata = Pick<ApiData, 'id' | 'size' | 'sizeBefore' | 'md5' | 'md5Encrypted' | 'createdAt'>;
3
- export type InternalData = DataMetadata & {
4
- key: string;
5
- };
6
- export type ApiData = NonNullable<RouterOutputs['cloud']['dataById']>;
File without changes
File without changes
File without changes