@secrecy/lib 1.77.0 → 1.79.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/client/SecrecyCloudClient.js +69 -22
- package/dist/lib/client/SecrecyGroupClient.js +10 -6
- package/dist/lib/client/SecrecyMailClient.js +28 -13
- package/dist/lib/client/index.js +11 -0
- package/dist/lib/client/types/identity.js +1 -0
- package/dist/lib/client/upload.js +9 -5
- package/dist/lib/crypto/domain.js +4 -4
- package/dist/types/client/SecrecyCloudClient.d.ts +5 -1
- package/dist/types/client/SecrecyMailClient.d.ts +1 -1
- package/dist/types/client/index.d.ts +3 -0
- package/dist/types/client/types/identity.d.ts +2 -0
- package/dist/types/client/types/index.d.ts +1 -0
- package/dist/types/client/upload.d.ts +3 -3
- package/dist/types/client.d.ts +556 -16
- package/dist/types/crypto/domain.d.ts +3 -3
- package/package.json +2 -2
|
@@ -20,16 +20,17 @@ export class SecrecyCloudClient {
|
|
|
20
20
|
const addDataToHistory = await this.#client.apiClient.cloud.addDataToHistory.mutate({
|
|
21
21
|
dataId,
|
|
22
22
|
nodeId,
|
|
23
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
23
24
|
});
|
|
24
25
|
const node = await apiNodeFullToInternalFull(addDataToHistory, this.#client.keyPairs);
|
|
25
26
|
const data = node.history.find((d) => d.id === dataId);
|
|
26
27
|
if (data !== undefined) {
|
|
27
|
-
const othersIdentities = Object.entries(node.identities).filter(([id]) => id !== this.#client.
|
|
28
|
+
const othersIdentities = Object.entries(node.identities).filter(([id]) => id !== this.#client.currentIdentity.identityPubKey);
|
|
28
29
|
const shares = othersIdentities.map(([publicKey]) => {
|
|
29
30
|
return {
|
|
30
31
|
pubKey: publicKey,
|
|
31
32
|
key: data.key
|
|
32
|
-
? sodium.to_hex(encryptCryptoBox(sodium.from_hex(data.key), publicKey, this.#client.
|
|
33
|
+
? sodium.to_hex(encryptCryptoBox(sodium.from_hex(data.key), publicKey, this.#client.currentIdentityPrivateKey))
|
|
33
34
|
: null,
|
|
34
35
|
};
|
|
35
36
|
});
|
|
@@ -37,6 +38,7 @@ export class SecrecyCloudClient {
|
|
|
37
38
|
dataId: data.id,
|
|
38
39
|
nodeId,
|
|
39
40
|
users: shares,
|
|
41
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
40
42
|
});
|
|
41
43
|
}
|
|
42
44
|
return internalNodeFullToNodeFull(node);
|
|
@@ -44,7 +46,7 @@ export class SecrecyCloudClient {
|
|
|
44
46
|
async uploadData(opts) {
|
|
45
47
|
return uploadData({
|
|
46
48
|
...opts,
|
|
47
|
-
|
|
49
|
+
currentIdentity: this.#client.currentIdentity,
|
|
48
50
|
keyPairs: this.#client.keyPairs,
|
|
49
51
|
apiClient: this.#client.apiClient,
|
|
50
52
|
});
|
|
@@ -60,21 +62,29 @@ export class SecrecyCloudClient {
|
|
|
60
62
|
return await this.saveInCloud({ dataId: uploadedData.id, name, nodeId });
|
|
61
63
|
}
|
|
62
64
|
async deletedNodes() {
|
|
63
|
-
const deletedNodes = await this.#client.apiClient.cloud.nodesDeleted.query({
|
|
65
|
+
const deletedNodes = await this.#client.apiClient.cloud.nodesDeleted.query({
|
|
66
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
67
|
+
});
|
|
64
68
|
return await Promise.all(deletedNodes.map(async (node) => await apiNodeToExternal(node, this.#client.keyPairs)));
|
|
65
69
|
}
|
|
66
70
|
async sharedNodes() {
|
|
67
|
-
const nodesShared = await this.#client.apiClient.cloud.nodesShared.query({
|
|
71
|
+
const nodesShared = await this.#client.apiClient.cloud.nodesShared.query({
|
|
72
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
73
|
+
});
|
|
68
74
|
return await Promise.all(nodesShared.map(async (node) => await apiNodeToExternal(node, this.#client.keyPairs)));
|
|
69
75
|
}
|
|
70
76
|
async nodesSharedWithMe(type = 'FOLDER') {
|
|
71
|
-
const nodesSharedWithMe = await this.#client.apiClient.cloud.nodesSharedWithMe.query({
|
|
77
|
+
const nodesSharedWithMe = await this.#client.apiClient.cloud.nodesSharedWithMe.query({
|
|
78
|
+
type,
|
|
79
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
80
|
+
});
|
|
72
81
|
return await Promise.all(nodesSharedWithMe.map(async (node) => await apiNodeToExternal(node, this.#client.keyPairs)));
|
|
73
82
|
}
|
|
74
83
|
async deleteNodeSharing({ nodeId, destPubKey, }) {
|
|
75
84
|
const { isDeleted } = await this.#client.apiClient.cloud.deleteNodeSharing.mutate({
|
|
76
85
|
nodeId,
|
|
77
86
|
destPubKey,
|
|
87
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
78
88
|
});
|
|
79
89
|
return isDeleted;
|
|
80
90
|
}
|
|
@@ -82,6 +92,7 @@ export class SecrecyCloudClient {
|
|
|
82
92
|
const { isDeleted } = await this.#client.apiClient.cloud.leaveSharing.mutate({
|
|
83
93
|
nodeId,
|
|
84
94
|
fromPubKey,
|
|
95
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
85
96
|
});
|
|
86
97
|
return isDeleted;
|
|
87
98
|
}
|
|
@@ -105,27 +116,32 @@ export class SecrecyCloudClient {
|
|
|
105
116
|
nodeId,
|
|
106
117
|
folderId: folderId ?? null,
|
|
107
118
|
name,
|
|
119
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
108
120
|
});
|
|
109
121
|
return isDuplicated;
|
|
110
122
|
}
|
|
111
123
|
async deleteNodeCloudTrash({ ids }) {
|
|
112
|
-
const { isDeleted } = await this.#client.apiClient.cloud.deleteNodeCloudTrash.mutate({
|
|
124
|
+
const { isDeleted } = await this.#client.apiClient.cloud.deleteNodeCloudTrash.mutate({
|
|
125
|
+
ids,
|
|
126
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
127
|
+
});
|
|
113
128
|
return isDeleted;
|
|
114
129
|
}
|
|
115
130
|
async createFolder({ name, parentFolderId, }) {
|
|
116
131
|
const { encryptedNameKey, encryptedName } = await generateAndEncryptNameAndKey({
|
|
117
132
|
name,
|
|
118
|
-
privateKey: this.#client.
|
|
119
|
-
publicKey: this.#client.
|
|
133
|
+
privateKey: this.#client.currentIdentityPrivateKey,
|
|
134
|
+
publicKey: this.#client.currentIdentity.identityPubKey,
|
|
120
135
|
});
|
|
121
136
|
const createdFolder = await this.#client.apiClient.cloud.createFolder.mutate({
|
|
122
137
|
name: encryptedName,
|
|
123
138
|
parentId: parentFolderId ?? null,
|
|
124
139
|
nameKey: encryptedNameKey,
|
|
140
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
125
141
|
});
|
|
126
142
|
const folder = await apiNodeToExternalNodeFull(createdFolder, this.#client.keyPairs);
|
|
127
143
|
if (folder.parent) {
|
|
128
|
-
const othersIdentities = Object.entries(folder.parent.identities).filter(([id]) => id !== this.#client.
|
|
144
|
+
const othersIdentities = Object.entries(folder.parent.identities).filter(([id]) => id !== this.#client.currentIdentity.identityPubKey);
|
|
129
145
|
// TODO: ??
|
|
130
146
|
if (othersIdentities.length > 0) {
|
|
131
147
|
await this.shareNode(othersIdentities.map(([identityPubKey, permissions]) => ({
|
|
@@ -145,17 +161,30 @@ export class SecrecyCloudClient {
|
|
|
145
161
|
const node = await this.#client.apiClient.cloud.nodeFullById.query({
|
|
146
162
|
id,
|
|
147
163
|
deleted,
|
|
164
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
148
165
|
});
|
|
149
166
|
return await apiNodeToExternalNodeFull(node, this.#client.keyPairs);
|
|
150
167
|
}
|
|
168
|
+
async nodes({ ids, deleted, }) {
|
|
169
|
+
const nodes = await this.#client.apiClient.cloud.nodeFullByIds.query({
|
|
170
|
+
ids,
|
|
171
|
+
deleted,
|
|
172
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
173
|
+
});
|
|
174
|
+
return await Promise.all(nodes.nodes.map((node) => apiNodeToExternalNodeFull(node, this.#client.keyPairs)));
|
|
175
|
+
}
|
|
151
176
|
async dataMetadata({ id }) {
|
|
152
|
-
const data = await this.#client.apiClient.cloud.dataById.query({
|
|
177
|
+
const data = await this.#client.apiClient.cloud.dataById.query({
|
|
178
|
+
id,
|
|
179
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
180
|
+
});
|
|
153
181
|
return apiDataToExternal(data, this.#client.keyPairs);
|
|
154
182
|
}
|
|
155
183
|
async shareNode(accesses, progress) {
|
|
156
184
|
// TODO: Validate input
|
|
157
185
|
const nodesMap = await this.#client.apiClient.cloud.shareNode.mutate({
|
|
158
186
|
accesses,
|
|
187
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
159
188
|
});
|
|
160
189
|
const maxNodesBatchSize = 1000;
|
|
161
190
|
const totalNodesToShare = Object.values(nodesMap).reduce((size, ids) => size + ids.length, 0);
|
|
@@ -235,6 +264,7 @@ export class SecrecyCloudClient {
|
|
|
235
264
|
const subState = finishInput.length > 0
|
|
236
265
|
? await this.#client.apiClient.cloud.shareNodeFinish.mutate({
|
|
237
266
|
accesses: finishInput,
|
|
267
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
238
268
|
})
|
|
239
269
|
: { isFinished: true, details: {} };
|
|
240
270
|
const currentProgress = Math.min((index + 1) * maxNodesBatchSize, totalNodesToShare);
|
|
@@ -298,6 +328,7 @@ export class SecrecyCloudClient {
|
|
|
298
328
|
id: nodeId,
|
|
299
329
|
isFavorite: isFavorite ?? null,
|
|
300
330
|
name,
|
|
331
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
301
332
|
});
|
|
302
333
|
return await apiNodeToExternalNodeFull(updateNode, this.#client.keyPairs);
|
|
303
334
|
}
|
|
@@ -308,6 +339,7 @@ export class SecrecyCloudClient {
|
|
|
308
339
|
}
|
|
309
340
|
const dataContent = await this.#client.apiClient.cloud.dataContentById.query({
|
|
310
341
|
id: dataId,
|
|
342
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
311
343
|
});
|
|
312
344
|
const totalBytes = Number(dataContent.sizeEncrypted ?? dataContent.size);
|
|
313
345
|
const progressParts = {};
|
|
@@ -329,6 +361,7 @@ export class SecrecyCloudClient {
|
|
|
329
361
|
}
|
|
330
362
|
const missingContents = await this.#client.apiClient.cloud.dataContentByIds.query({
|
|
331
363
|
ids: dataIds.filter((dataId) => !cachedData.some((datum) => datum.id === dataId)),
|
|
364
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
332
365
|
});
|
|
333
366
|
const allDataContents = [
|
|
334
367
|
...missingContents.map((data) => ({
|
|
@@ -358,28 +391,36 @@ export class SecrecyCloudClient {
|
|
|
358
391
|
}));
|
|
359
392
|
}
|
|
360
393
|
async deleteNodes({ nodeIds, }) {
|
|
361
|
-
return this.#client.apiClient.cloud.deleteNodes.mutate({
|
|
394
|
+
return this.#client.apiClient.cloud.deleteNodes.mutate({
|
|
395
|
+
ids: nodeIds,
|
|
396
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
397
|
+
});
|
|
362
398
|
}
|
|
363
399
|
async deleteData({ dataId, nodeId, }) {
|
|
364
400
|
const { isDeleted } = await this.#client.apiClient.cloud.deleteData.mutate({
|
|
365
401
|
dataId,
|
|
366
402
|
nodeId,
|
|
403
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
367
404
|
});
|
|
368
405
|
return isDeleted;
|
|
369
406
|
}
|
|
370
407
|
async deleteNode({ nodeId }) {
|
|
371
408
|
const { isDeleted } = await this.#client.apiClient.cloud.deleteNode.mutate({
|
|
372
409
|
id: nodeId,
|
|
410
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
373
411
|
});
|
|
374
412
|
return isDeleted;
|
|
375
413
|
}
|
|
376
414
|
async emptyTrash() {
|
|
377
|
-
const { isCleaned } = await this.#client.apiClient.cloud.emptyNodeCloudTrash.mutate({
|
|
415
|
+
const { isCleaned } = await this.#client.apiClient.cloud.emptyNodeCloudTrash.mutate({
|
|
416
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
417
|
+
});
|
|
378
418
|
return isCleaned;
|
|
379
419
|
}
|
|
380
420
|
async recoverNode(id) {
|
|
381
421
|
const { isRecovered } = await this.#client.apiClient.cloud.recoverNode.mutate({
|
|
382
422
|
id,
|
|
423
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
383
424
|
});
|
|
384
425
|
return isRecovered;
|
|
385
426
|
}
|
|
@@ -387,6 +428,7 @@ export class SecrecyCloudClient {
|
|
|
387
428
|
const { isMoved } = await this.#client.apiClient.cloud.moveNodes.mutate({
|
|
388
429
|
ids: nodeIds,
|
|
389
430
|
parentId: parentNodeId ?? null,
|
|
431
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
390
432
|
});
|
|
391
433
|
return isMoved;
|
|
392
434
|
}
|
|
@@ -429,7 +471,7 @@ export class SecrecyCloudClient {
|
|
|
429
471
|
}
|
|
430
472
|
const senderPubKey = await this.#client.app.userPublicKey(mail.sender.id);
|
|
431
473
|
const dataKey = attachment.key
|
|
432
|
-
? decryptCryptoBox(sodium.from_hex(attachment.key), senderPubKey, this.#client.
|
|
474
|
+
? decryptCryptoBox(sodium.from_hex(attachment.key), senderPubKey, this.#client.currentIdentityPrivateKey)
|
|
433
475
|
: null;
|
|
434
476
|
key = dataKey !== null ? sodium.to_hex(dataKey) : null;
|
|
435
477
|
}
|
|
@@ -441,12 +483,12 @@ export class SecrecyCloudClient {
|
|
|
441
483
|
key = data.key;
|
|
442
484
|
}
|
|
443
485
|
key = key
|
|
444
|
-
? sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), this.#client.
|
|
486
|
+
? sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey))
|
|
445
487
|
: null;
|
|
446
488
|
const { encryptedNameKey, encryptedName } = await generateAndEncryptNameAndKey({
|
|
447
489
|
name,
|
|
448
|
-
privateKey: this.#client.
|
|
449
|
-
publicKey: this.#client.
|
|
490
|
+
privateKey: this.#client.currentIdentityPrivateKey,
|
|
491
|
+
publicKey: this.#client.currentIdentity.identityPubKey,
|
|
450
492
|
});
|
|
451
493
|
const saveInCloud = await this.#client.apiClient.cloud.saveInCloud.mutate({
|
|
452
494
|
dataId,
|
|
@@ -454,10 +496,11 @@ export class SecrecyCloudClient {
|
|
|
454
496
|
nodeId: nodeId ?? null,
|
|
455
497
|
fileName: encryptedName,
|
|
456
498
|
nameKey: encryptedNameKey,
|
|
499
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
457
500
|
});
|
|
458
501
|
const node = await apiNodeToExternalNodeFull(saveInCloud, this.#client.keyPairs);
|
|
459
502
|
if (node.parent) {
|
|
460
|
-
const othersIdentities = Object.entries(node.parent.identities).filter(([id]) => id !== this.#client.
|
|
503
|
+
const othersIdentities = Object.entries(node.parent.identities).filter(([id]) => id !== this.#client.currentIdentity.identityPubKey);
|
|
461
504
|
// TODO: ??
|
|
462
505
|
if (othersIdentities.length > 0) {
|
|
463
506
|
await this.shareNode(othersIdentities.map(([identityPubKey, permissions]) => ({
|
|
@@ -508,6 +551,7 @@ export class SecrecyCloudClient {
|
|
|
508
551
|
const fetchedNodes = missingNodeIds.length > 0
|
|
509
552
|
? await this.#client.apiClient.cloud.nodesForEncryption.query({
|
|
510
553
|
ids: missingNodeIds,
|
|
554
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
511
555
|
})
|
|
512
556
|
: [];
|
|
513
557
|
const diff = missingNodeIds.filter((id) => !fetchedNodes.some((node) => node.id === id));
|
|
@@ -532,10 +576,10 @@ export class SecrecyCloudClient {
|
|
|
532
576
|
}
|
|
533
577
|
nodesMappedUsers[pubKey].push({
|
|
534
578
|
id: node.id,
|
|
535
|
-
nameKey: sodium.to_hex(encryptCryptoBox(sodium.from_hex(node.access.nameKey), pubKey, this.#client.
|
|
579
|
+
nameKey: sodium.to_hex(encryptCryptoBox(sodium.from_hex(node.access.nameKey), pubKey, this.#client.currentIdentityPrivateKey)),
|
|
536
580
|
data: node.history.map((f) => ({
|
|
537
581
|
id: f.id,
|
|
538
|
-
key: sodium.to_hex(encryptCryptoBox(sodium.from_hex(f.key), pubKey, this.#client.
|
|
582
|
+
key: sodium.to_hex(encryptCryptoBox(sodium.from_hex(f.key), pubKey, this.#client.currentIdentityPrivateKey)),
|
|
539
583
|
})),
|
|
540
584
|
});
|
|
541
585
|
}
|
|
@@ -575,7 +619,10 @@ export class SecrecyCloudClient {
|
|
|
575
619
|
return this.#client.apiClient.cloud.dataLinks.query(input);
|
|
576
620
|
}
|
|
577
621
|
checkAccesses(input) {
|
|
578
|
-
return this.#client.apiClient.cloud.checkAccesses.query(
|
|
622
|
+
return this.#client.apiClient.cloud.checkAccesses.query({
|
|
623
|
+
...input,
|
|
624
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
625
|
+
});
|
|
579
626
|
}
|
|
580
627
|
createPublicDataLink(input) {
|
|
581
628
|
if (input.expireAt && input.expireAt <= new Date()) {
|
|
@@ -609,7 +656,7 @@ export class SecrecyCloudClient {
|
|
|
609
656
|
? dataContent.senderPublicKey
|
|
610
657
|
: dataContent.type === 'cloud' || dataContent.type === 'lite'
|
|
611
658
|
? dataContent.sharedByPublicKey
|
|
612
|
-
: this.#client.
|
|
659
|
+
: this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey)
|
|
613
660
|
: null;
|
|
614
661
|
const src = key
|
|
615
662
|
? await decrypt(key, encryptedContent, progressDecrypt, signal)
|
|
@@ -12,21 +12,25 @@ export class SecrecyGroupClient {
|
|
|
12
12
|
const opts = {
|
|
13
13
|
pubKey: input.pubKey,
|
|
14
14
|
role: input.role,
|
|
15
|
-
fromPubKey: this.#client.uaIdentity.identityPubKey,
|
|
16
15
|
id: input.id,
|
|
17
|
-
encPriv: sodium.to_hex(encryptCryptoBox(sodium.from_hex(groupIdentity.identityPubKey), input.pubKey, this.#client.
|
|
16
|
+
encPriv: sodium.to_hex(encryptCryptoBox(sodium.from_hex(groupIdentity.identityPubKey), input.pubKey, this.#client.currentIdentityPrivateKey)),
|
|
18
17
|
};
|
|
19
|
-
return this.#client.apiClient.group.addMember.mutate(
|
|
18
|
+
return this.#client.apiClient.group.addMember.mutate({
|
|
19
|
+
...opts,
|
|
20
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
21
|
+
});
|
|
20
22
|
}
|
|
21
23
|
async create(input) {
|
|
22
24
|
const keyPair = generateCryptoBoxKeyPair();
|
|
23
25
|
const opts = {
|
|
24
26
|
name: input.name,
|
|
25
|
-
fromPubKey: this.#client.uaIdentity.identityPubKey,
|
|
26
27
|
pubKey: keyPair.publicKey,
|
|
27
|
-
encPriv: sodium.to_hex(encryptCryptoBox(sodium.from_hex(keyPair.privateKey), this.#client.
|
|
28
|
+
encPriv: sodium.to_hex(encryptCryptoBox(sodium.from_hex(keyPair.privateKey), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey)),
|
|
28
29
|
};
|
|
29
|
-
return this.#client.apiClient.group.create.mutate(
|
|
30
|
+
return this.#client.apiClient.group.create.mutate({
|
|
31
|
+
...opts,
|
|
32
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
33
|
+
});
|
|
30
34
|
}
|
|
31
35
|
async deleteMember(input) {
|
|
32
36
|
return this.#client.apiClient.group.deleteMember.mutate(input);
|
|
@@ -16,12 +16,14 @@ export class SecrecyMailClient {
|
|
|
16
16
|
async recover({ mailId }) {
|
|
17
17
|
const { isRecovered } = await this.#client.apiClient.mail.recover.mutate({
|
|
18
18
|
id: mailId,
|
|
19
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
19
20
|
});
|
|
20
21
|
return isRecovered;
|
|
21
22
|
}
|
|
22
23
|
async deletedMails({ mailType, }) {
|
|
23
24
|
const deletedMails = await this.#client.apiClient.mail.deleted.query({
|
|
24
25
|
type: mailType,
|
|
26
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
25
27
|
});
|
|
26
28
|
return await Promise.all(deletedMails.map(async (mail) => await convertInternalMailToExternal({
|
|
27
29
|
mail,
|
|
@@ -73,7 +75,7 @@ export class SecrecyMailClient {
|
|
|
73
75
|
throw new Error(`File ${f.name} (${f.id}) does not exists`);
|
|
74
76
|
}
|
|
75
77
|
}
|
|
76
|
-
f.name = sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#client.
|
|
78
|
+
f.name = sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey));
|
|
77
79
|
}
|
|
78
80
|
}
|
|
79
81
|
const updateDraftMail = await this.#client.apiClient.mail.updateDraft.mutate({
|
|
@@ -81,14 +83,15 @@ export class SecrecyMailClient {
|
|
|
81
83
|
recipients: recipients ?? null,
|
|
82
84
|
replyToId: replyToId ?? null,
|
|
83
85
|
body: body !== undefined
|
|
84
|
-
? sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#client.
|
|
86
|
+
? sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey))
|
|
85
87
|
: null,
|
|
86
88
|
subject: subject !== undefined
|
|
87
|
-
? sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#client.
|
|
89
|
+
? sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey))
|
|
88
90
|
: null,
|
|
89
91
|
senderFiles: senderFiles ?? null,
|
|
90
92
|
hash,
|
|
91
93
|
hashKey,
|
|
94
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
92
95
|
});
|
|
93
96
|
return (await convertInternalMailToExternal({
|
|
94
97
|
mail: updateDraftMail,
|
|
@@ -104,16 +107,20 @@ export class SecrecyMailClient {
|
|
|
104
107
|
async deleteTrash({ ids }) {
|
|
105
108
|
const { isDeleted } = await this.#client.apiClient.mail.deleteTrash.mutate({
|
|
106
109
|
ids,
|
|
110
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
107
111
|
});
|
|
108
112
|
return isDeleted;
|
|
109
113
|
}
|
|
110
114
|
async emptyTrash() {
|
|
111
|
-
const { isDeleted } = await this.#client.apiClient.mail.emptyTrash.mutate({
|
|
115
|
+
const { isDeleted } = await this.#client.apiClient.mail.emptyTrash.mutate({
|
|
116
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
117
|
+
});
|
|
112
118
|
return isDeleted;
|
|
113
119
|
}
|
|
114
120
|
async delete({ mailId }) {
|
|
115
121
|
const { isDeleted } = await this.#client.apiClient.mail.delete.mutate({
|
|
116
122
|
id: mailId,
|
|
123
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
117
124
|
});
|
|
118
125
|
return isDeleted;
|
|
119
126
|
}
|
|
@@ -201,17 +208,18 @@ export class SecrecyMailClient {
|
|
|
201
208
|
}
|
|
202
209
|
senderFiles.push({
|
|
203
210
|
id: data.id,
|
|
204
|
-
name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#client.
|
|
211
|
+
name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey)),
|
|
205
212
|
});
|
|
206
213
|
}
|
|
207
214
|
const createDraftMail = await this.#client.apiClient.mail.createDraft.mutate({
|
|
208
215
|
recipients,
|
|
209
216
|
replyToId,
|
|
210
|
-
body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#client.
|
|
211
|
-
subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#client.
|
|
217
|
+
body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey)),
|
|
218
|
+
subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), this.#client.currentIdentity.identityPubKey, this.#client.currentIdentityPrivateKey)),
|
|
212
219
|
senderFiles,
|
|
213
220
|
hash,
|
|
214
221
|
hashKey,
|
|
222
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
215
223
|
});
|
|
216
224
|
return (await convertInternalMailToExternal({
|
|
217
225
|
mail: createDraftMail,
|
|
@@ -221,17 +229,22 @@ export class SecrecyMailClient {
|
|
|
221
229
|
async read({ mailId }) {
|
|
222
230
|
const { isRead } = await this.#client.apiClient.mail.read.mutate({
|
|
223
231
|
id: mailId,
|
|
232
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
224
233
|
});
|
|
225
234
|
return isRead;
|
|
226
235
|
}
|
|
227
236
|
async unread({ mailId }) {
|
|
228
237
|
const { isUnread } = await this.#client.apiClient.mail.unread.mutate({
|
|
229
238
|
id: mailId,
|
|
239
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
230
240
|
});
|
|
231
241
|
return isUnread;
|
|
232
242
|
}
|
|
233
243
|
async receivedMails(input) {
|
|
234
|
-
const receivedMails = await this.#client.apiClient.mail.received.query(
|
|
244
|
+
const receivedMails = await this.#client.apiClient.mail.received.query({
|
|
245
|
+
...input,
|
|
246
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
247
|
+
});
|
|
235
248
|
return await Promise.all(receivedMails.map(async (mail) => (await convertInternalMailToExternal({
|
|
236
249
|
mail,
|
|
237
250
|
keyPairs: this.#client.keyPairs,
|
|
@@ -252,7 +265,9 @@ export class SecrecyMailClient {
|
|
|
252
265
|
}))));
|
|
253
266
|
}
|
|
254
267
|
async unreadReceivedMailsCount() {
|
|
255
|
-
const unreadReceivedMailsCount = await this.#client.apiClient.mail.unreadReceivedCount.query({
|
|
268
|
+
const unreadReceivedMailsCount = await this.#client.apiClient.mail.unreadReceivedCount.query({
|
|
269
|
+
fromIdentityPubKey: this.#client.currentIdentity.identityPubKey,
|
|
270
|
+
});
|
|
256
271
|
return unreadReceivedMailsCount;
|
|
257
272
|
}
|
|
258
273
|
_eachUser = async (data, subject, body, idOrMail) => {
|
|
@@ -272,17 +287,17 @@ export class SecrecyMailClient {
|
|
|
272
287
|
const key = dataInHistory.key;
|
|
273
288
|
attachments.push({
|
|
274
289
|
dataId: f.id,
|
|
275
|
-
name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), pubKey, this.#client.
|
|
290
|
+
name: sodium.to_hex(encryptCryptoBox(sodium.from_string(f.name), pubKey, this.#client.currentIdentityPrivateKey)),
|
|
276
291
|
key: key
|
|
277
|
-
? sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#client.
|
|
292
|
+
? sodium.to_hex(encryptCryptoBox(sodium.from_hex(key), pubKey, this.#client.currentIdentityPrivateKey))
|
|
278
293
|
: null,
|
|
279
294
|
});
|
|
280
295
|
}
|
|
281
296
|
return {
|
|
282
297
|
// recipientId: userId,
|
|
283
298
|
recipientPubKey: pubKey,
|
|
284
|
-
body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), pubKey, this.#client.
|
|
285
|
-
subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), pubKey, this.#client.
|
|
299
|
+
body: sodium.to_hex(encryptCryptoBox(sodium.from_string(body), pubKey, this.#client.currentIdentityPrivateKey)),
|
|
300
|
+
subject: sodium.to_hex(encryptCryptoBox(sodium.from_string(subject), pubKey, this.#client.currentIdentityPrivateKey)),
|
|
286
301
|
attachments,
|
|
287
302
|
};
|
|
288
303
|
};
|
package/dist/lib/client/index.js
CHANGED
|
@@ -15,6 +15,7 @@ import { SecrecyIdentityClient } from './SecrecyIdentityClient.js';
|
|
|
15
15
|
export class SecrecyClient extends BaseClient {
|
|
16
16
|
#groupIdentities;
|
|
17
17
|
#uaIdentity;
|
|
18
|
+
#currentGroupIdentity = null;
|
|
18
19
|
#keyPairs;
|
|
19
20
|
cloud;
|
|
20
21
|
mail;
|
|
@@ -61,6 +62,16 @@ export class SecrecyClient extends BaseClient {
|
|
|
61
62
|
this.group = new SecrecyGroupClient(this);
|
|
62
63
|
this.identity = new SecrecyIdentityClient(this);
|
|
63
64
|
}
|
|
65
|
+
get currentIdentity() {
|
|
66
|
+
return this.#currentGroupIdentity ?? this.#uaIdentity;
|
|
67
|
+
}
|
|
68
|
+
get currentIdentityPrivateKey() {
|
|
69
|
+
return this.getPrivateKey(this.currentIdentity.identityPubKey);
|
|
70
|
+
}
|
|
71
|
+
set currentGroup(groupId) {
|
|
72
|
+
this.#currentGroupIdentity =
|
|
73
|
+
this.#groupIdentities.find((g) => g.groupId === groupId) ?? null;
|
|
74
|
+
}
|
|
64
75
|
get publicKey() {
|
|
65
76
|
return this.#uaIdentity.identityPubKey;
|
|
66
77
|
}
|
|
@@ -11,6 +11,7 @@ export const groupSchema = z.object({
|
|
|
11
11
|
groupId: z.string(),
|
|
12
12
|
groupRole: z.enum(['ADMIN', 'MEMBER']),
|
|
13
13
|
sharedByPubKey: z.string(),
|
|
14
|
+
sharedToPubKey: z.string(),
|
|
14
15
|
groupOwnerPubKey: z.string(),
|
|
15
16
|
});
|
|
16
17
|
export const accessIdentitySchema = z.discriminatedUnion('kind', [
|
|
@@ -11,11 +11,11 @@ import { promiseAllLimit } from '../utils/promise.js';
|
|
|
11
11
|
import { encryptDataAndKey } from '../crypto/domain.js';
|
|
12
12
|
import { derivePassword, generatePassword } from '../crypto/helpers.js';
|
|
13
13
|
import { decryptCryptoBox, encryptSecretBox } from '../crypto/index.js';
|
|
14
|
-
export async function uploadData({ storageType, data, password, forcePassword = false, encrypted = true, encryptProgress, uploadProgress, signal, meta,
|
|
14
|
+
export async function uploadData({ storageType, data, password, forcePassword = false, encrypted = true, encryptProgress, uploadProgress, signal, meta, currentIdentity, keyPairs, apiClient, }) {
|
|
15
15
|
if (!encrypted && (password || forcePassword)) {
|
|
16
16
|
throw new Error('Cannot share unencrypted data with a password!');
|
|
17
17
|
}
|
|
18
|
-
if (encrypted && !password && !forcePassword && !
|
|
18
|
+
if (encrypted && !password && !forcePassword && !currentIdentity) {
|
|
19
19
|
throw new Error('Cannot share encrypted data without a password!');
|
|
20
20
|
}
|
|
21
21
|
apiClient ??= getTrpcGuestClient();
|
|
@@ -37,7 +37,7 @@ export async function uploadData({ storageType, data, password, forcePassword =
|
|
|
37
37
|
if (storageType === 'lite' && dataBuffer.byteLength > kiloToBytes(1024)) {
|
|
38
38
|
throw new Error('The data is too big for lite upload!');
|
|
39
39
|
}
|
|
40
|
-
if (!
|
|
40
|
+
if (!currentIdentity && storageType === 'cold') {
|
|
41
41
|
throw new Error('Cold storage is only for logged users!');
|
|
42
42
|
}
|
|
43
43
|
const compressed = encrypted ? compress(dataBuffer) : dataBuffer;
|
|
@@ -45,7 +45,7 @@ export async function uploadData({ storageType, data, password, forcePassword =
|
|
|
45
45
|
? await encryptDataAndKey({
|
|
46
46
|
data: compressed,
|
|
47
47
|
progress: encryptProgress,
|
|
48
|
-
|
|
48
|
+
currentIdentity,
|
|
49
49
|
keyPairs,
|
|
50
50
|
signal,
|
|
51
51
|
})
|
|
@@ -74,7 +74,7 @@ export async function uploadData({ storageType, data, password, forcePassword =
|
|
|
74
74
|
key = dataKey;
|
|
75
75
|
}
|
|
76
76
|
else {
|
|
77
|
-
if (!
|
|
77
|
+
if (!currentIdentity) {
|
|
78
78
|
throw new Error('Unable to encrypt data without keyPair!');
|
|
79
79
|
}
|
|
80
80
|
if (!data.key) {
|
|
@@ -104,6 +104,7 @@ export async function uploadData({ storageType, data, password, forcePassword =
|
|
|
104
104
|
key: encryptedDataKey ? sodium.to_hex(encryptedDataKey) : undefined,
|
|
105
105
|
md5Encrypted,
|
|
106
106
|
md5: md5Data,
|
|
107
|
+
fromIdentityPubKey: currentIdentity?.identityPubKey,
|
|
107
108
|
...filetype,
|
|
108
109
|
}
|
|
109
110
|
: {
|
|
@@ -111,6 +112,7 @@ export async function uploadData({ storageType, data, password, forcePassword =
|
|
|
111
112
|
content: Buffer.from(encryptedData),
|
|
112
113
|
md5: md5Data,
|
|
113
114
|
size: BigInt(dataBuffer.byteLength),
|
|
115
|
+
fromIdentityPubKey: currentIdentity?.identityPubKey,
|
|
114
116
|
...filetype,
|
|
115
117
|
};
|
|
116
118
|
const uploadData = await apiClient.cloud.uploadLiteData.mutate(uploadDataArgs, { signal });
|
|
@@ -146,12 +148,14 @@ export async function uploadData({ storageType, data, password, forcePassword =
|
|
|
146
148
|
key: encryptedDataKey ? sodium.to_hex(encryptedDataKey) : undefined,
|
|
147
149
|
md5Encrypted,
|
|
148
150
|
md5: md5Data,
|
|
151
|
+
fromIdentityPubKey: currentIdentity?.identityPubKey,
|
|
149
152
|
...filetype,
|
|
150
153
|
}
|
|
151
154
|
: {
|
|
152
155
|
type: 'unencrypted',
|
|
153
156
|
md5: md5Data,
|
|
154
157
|
size: BigInt(dataBuffer.byteLength),
|
|
158
|
+
fromIdentityPubKey: currentIdentity?.identityPubKey,
|
|
155
159
|
...filetype,
|
|
156
160
|
};
|
|
157
161
|
const uploadDataCaller = storageType === 's3'
|
|
@@ -10,10 +10,10 @@ import { concatenate } from '../utils/array.js';
|
|
|
10
10
|
* If a string is provided as keypair, it should be considered as guest with password case.
|
|
11
11
|
* If keypair is not provided, then we generate a key to be used as password for guest too.
|
|
12
12
|
*/
|
|
13
|
-
export async function encryptDataAndKey({ data,
|
|
13
|
+
export async function encryptDataAndKey({ data, currentIdentity, keyPairs, progress, signal, }) {
|
|
14
14
|
const dataKey = secretStreamKeygen();
|
|
15
15
|
const { data: encryptedData, md5: md5Data, md5Encrypted, } = await encrypt(dataKey, data, progress, signal);
|
|
16
|
-
if (!
|
|
16
|
+
if (!currentIdentity || !keyPairs) {
|
|
17
17
|
return {
|
|
18
18
|
encryptedData,
|
|
19
19
|
dataKey,
|
|
@@ -21,11 +21,11 @@ export async function encryptDataAndKey({ data, uaIdentity, keyPairs, progress,
|
|
|
21
21
|
md5Encrypted,
|
|
22
22
|
};
|
|
23
23
|
}
|
|
24
|
-
const priv = keyPairs[
|
|
24
|
+
const priv = keyPairs[currentIdentity.identityPubKey];
|
|
25
25
|
if (!priv) {
|
|
26
26
|
throw new Error('No private key found for user app identity');
|
|
27
27
|
}
|
|
28
|
-
const encDataKey = encryptCryptoBox(dataKey,
|
|
28
|
+
const encDataKey = encryptCryptoBox(dataKey, currentIdentity.identityPubKey, priv);
|
|
29
29
|
return {
|
|
30
30
|
encryptedDataKey: encDataKey,
|
|
31
31
|
encryptedData,
|
|
@@ -52,6 +52,10 @@ export declare class SecrecyCloudClient {
|
|
|
52
52
|
id?: string | null | undefined;
|
|
53
53
|
deleted?: boolean | null | undefined;
|
|
54
54
|
}): Promise<NodeFull>;
|
|
55
|
+
nodes({ ids, deleted, }: {
|
|
56
|
+
ids: string[];
|
|
57
|
+
deleted?: boolean | null | undefined;
|
|
58
|
+
}): Promise<NodeFull[]>;
|
|
55
59
|
dataMetadata({ id }: {
|
|
56
60
|
id: string;
|
|
57
61
|
}): Promise<DataMetadata>;
|
|
@@ -124,7 +128,7 @@ export declare class SecrecyCloudClient {
|
|
|
124
128
|
createdByOrgId: string | null;
|
|
125
129
|
createdByAppId: string | null;
|
|
126
130
|
}[]>;
|
|
127
|
-
checkAccesses(input: RouterInputs['cloud']['checkAccesses']): Promise<{
|
|
131
|
+
checkAccesses(input: Omit<RouterInputs['cloud']['checkAccesses'], 'fromIdentityPubKey'>): Promise<{
|
|
128
132
|
isMatching: true;
|
|
129
133
|
} | {
|
|
130
134
|
isMatching: false;
|
|
@@ -33,7 +33,7 @@ export declare class SecrecyMailClient {
|
|
|
33
33
|
unread({ mailId }: {
|
|
34
34
|
mailId: string;
|
|
35
35
|
}): Promise<boolean>;
|
|
36
|
-
receivedMails(input: RouterInputs['mail']['received']): Promise<ReceivedMail[]>;
|
|
36
|
+
receivedMails(input: Omit<RouterInputs['mail']['received'], 'fromIdentityPubKey'>): Promise<ReceivedMail[]>;
|
|
37
37
|
sentMails(input: RouterInputs['mail']['sent']): Promise<SentMail[]>;
|
|
38
38
|
draftMails(input: RouterInputs['mail']['draft']): Promise<DraftMail[]>;
|
|
39
39
|
unreadReceivedMailsCount(): Promise<number>;
|
|
@@ -37,6 +37,9 @@ export declare class SecrecyClient extends BaseClient {
|
|
|
37
37
|
group: SecrecyGroupClient;
|
|
38
38
|
identity: SecrecyIdentityClient;
|
|
39
39
|
constructor(opts: SecrecyClientOptions);
|
|
40
|
+
get currentIdentity(): Readonly<AccessIdentity>;
|
|
41
|
+
get currentIdentityPrivateKey(): string;
|
|
42
|
+
set currentGroup(groupId: string | null);
|
|
40
43
|
get publicKey(): string;
|
|
41
44
|
get apiClient(): Readonly<ApiClient>;
|
|
42
45
|
get keyPairs(): Readonly<Record<string, string>>;
|
|
@@ -14,6 +14,7 @@ export declare const groupSchema: z.ZodObject<{
|
|
|
14
14
|
MEMBER: "MEMBER";
|
|
15
15
|
}>;
|
|
16
16
|
sharedByPubKey: z.ZodString;
|
|
17
|
+
sharedToPubKey: z.ZodString;
|
|
17
18
|
groupOwnerPubKey: z.ZodString;
|
|
18
19
|
}, z.core.$strip>;
|
|
19
20
|
export declare const accessIdentitySchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
@@ -30,6 +31,7 @@ export declare const accessIdentitySchema: z.ZodDiscriminatedUnion<[z.ZodObject<
|
|
|
30
31
|
MEMBER: "MEMBER";
|
|
31
32
|
}>;
|
|
32
33
|
sharedByPubKey: z.ZodString;
|
|
34
|
+
sharedToPubKey: z.ZodString;
|
|
33
35
|
groupOwnerPubKey: z.ZodString;
|
|
34
36
|
}, z.core.$strip>], "kind">;
|
|
35
37
|
export type AccessIdentity = z.infer<typeof accessIdentitySchema>;
|