@secrecy/lib 1.62.0-feat-node-sharing.8 → 1.62.0-feat-node-sharing.10
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.
|
@@ -305,10 +305,11 @@ export class SecrecyCloudClient {
|
|
|
305
305
|
const users = folder.parent?.users?.filter(([u]) => u.id !== this.#client.app.userId) ??
|
|
306
306
|
[];
|
|
307
307
|
if (users.length > 0) {
|
|
308
|
-
await this.shareNode({
|
|
308
|
+
await this.shareNode(users.map(([user, rights]) => ({
|
|
309
|
+
userId: user.id,
|
|
310
|
+
rights,
|
|
309
311
|
nodeId: folder.id,
|
|
310
|
-
|
|
311
|
-
});
|
|
312
|
+
})));
|
|
312
313
|
}
|
|
313
314
|
return folder;
|
|
314
315
|
}
|
|
@@ -326,44 +327,110 @@ export class SecrecyCloudClient {
|
|
|
326
327
|
return apiDataToExternal(data, this.#keys);
|
|
327
328
|
}
|
|
328
329
|
async shareNode(input, progress) {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
: input.users.map(({ id }) => id);
|
|
336
|
-
const [publicKeysMap, nodesIdsMap] = await Promise.all([
|
|
337
|
-
this.#client.app.userPublicKey(userIds),
|
|
338
|
-
this.#apiClient.cloud.shareNode.mutate('nodes' in input
|
|
339
|
-
? input.nodes
|
|
340
|
-
: {
|
|
341
|
-
nodeId: input.nodeId,
|
|
342
|
-
userIds: input.users.map(({ id }) => id),
|
|
343
|
-
}),
|
|
344
|
-
]);
|
|
330
|
+
// TODO: Validate input
|
|
331
|
+
const nodesMap = await this.#apiClient.cloud.shareNode.mutate(input);
|
|
332
|
+
const neededUserKey = Object.entries(nodesMap)
|
|
333
|
+
.filter(([, nodes]) => nodes.some((node) => node.includeKeys))
|
|
334
|
+
.map(([userId]) => userId);
|
|
335
|
+
const publicKeysMap = await this.#client.app.userPublicKey(neededUserKey);
|
|
345
336
|
const maxNodesBatchSize = 1000;
|
|
346
|
-
const totalNodesToShare = Object.values(
|
|
337
|
+
const totalNodesToShare = Object.values(nodesMap).reduce((size, ids) => size + ids.length, 0);
|
|
338
|
+
progress?.({
|
|
339
|
+
total: totalNodesToShare,
|
|
340
|
+
current: 0,
|
|
341
|
+
percent: 0,
|
|
342
|
+
});
|
|
347
343
|
const chunks = totalNodesToShare > maxNodesBatchSize
|
|
348
|
-
? chunkByTotalItems(
|
|
349
|
-
: [
|
|
344
|
+
? chunkByTotalItems(nodesMap, maxNodesBatchSize)
|
|
345
|
+
: [nodesMap];
|
|
350
346
|
const details = await chunks.reduce(async (pendingState, nodesMap, index) => {
|
|
351
347
|
const state = await pendingState;
|
|
352
|
-
const
|
|
353
|
-
|
|
354
|
-
|
|
348
|
+
const nodesToEncrypt = Object.fromEntries(Object.entries(nodesMap).map(([key, value]) => [
|
|
349
|
+
key,
|
|
350
|
+
value.filter((node) => node.includeKeys).map((node) => node.nodeId),
|
|
351
|
+
]));
|
|
352
|
+
const infos = await this.encryptNodesForUsers(nodesToEncrypt, publicKeysMap);
|
|
353
|
+
const shares = Array.isArray(input)
|
|
354
|
+
? input
|
|
355
|
+
: 'userIds' in input
|
|
356
|
+
? 'nodeIds' in input
|
|
357
|
+
? input.userIds.flatMap((userId) => input.nodeIds.map((nodeId) => ({
|
|
358
|
+
rights: input.rights,
|
|
359
|
+
userId,
|
|
360
|
+
nodeId,
|
|
361
|
+
})))
|
|
362
|
+
: input.userIds.map((userId) => ({
|
|
363
|
+
rights: input.rights,
|
|
364
|
+
userId,
|
|
365
|
+
nodeId: input.nodeId,
|
|
366
|
+
}))
|
|
367
|
+
: input.nodeIds.map((nodeId) => ({
|
|
368
|
+
rights: input.rights,
|
|
369
|
+
nodeId,
|
|
370
|
+
userId: input.userId,
|
|
371
|
+
}));
|
|
372
|
+
const nodesToUpdateRights = Object.fromEntries(Object.entries(nodesMap).map(([userId, nodes]) => [
|
|
373
|
+
userId,
|
|
374
|
+
nodes
|
|
375
|
+
.filter((node) => !node.includeKeys)
|
|
376
|
+
.map((node) => {
|
|
377
|
+
const share = shares.find((share) => share.nodeId === node.nodeId && share.userId === userId);
|
|
378
|
+
if (!share) {
|
|
379
|
+
throw new Error('Unable to retrieve rights!');
|
|
380
|
+
}
|
|
381
|
+
return {
|
|
382
|
+
nodeId: node.nodeId,
|
|
383
|
+
userId: userId,
|
|
384
|
+
rights: share.rights,
|
|
385
|
+
};
|
|
386
|
+
}),
|
|
387
|
+
]));
|
|
388
|
+
const withKeys = Object.fromEntries(Object.entries(infos).map('rights' in input
|
|
389
|
+
? ([userId, nodes]) => [
|
|
390
|
+
userId,
|
|
391
|
+
{ userId, nodes, rights: input.rights },
|
|
392
|
+
]
|
|
355
393
|
: ([userId, nodes]) => {
|
|
356
|
-
const
|
|
357
|
-
if (!
|
|
358
|
-
throw new Error(
|
|
394
|
+
const share = shares.find((share) => share.userId === userId && share.nodeId === nodes[0].id);
|
|
395
|
+
if (!share) {
|
|
396
|
+
throw new Error('Unable to retrieve rights!');
|
|
359
397
|
}
|
|
360
|
-
return { userId, nodes, rights:
|
|
398
|
+
return [userId, { userId, nodes, rights: share.rights }];
|
|
361
399
|
}));
|
|
400
|
+
const finishInput = [];
|
|
401
|
+
for (const [userId, nodes] of Object.entries(withKeys)) {
|
|
402
|
+
finishInput.push({
|
|
403
|
+
userId,
|
|
404
|
+
rights: nodes.rights,
|
|
405
|
+
nodes: nodes.nodes.map((node) => ({
|
|
406
|
+
id: node.id,
|
|
407
|
+
nameKey: node.nameKey,
|
|
408
|
+
data: node.data.map((d) => ({
|
|
409
|
+
id: d.id,
|
|
410
|
+
key: d.key,
|
|
411
|
+
})),
|
|
412
|
+
})),
|
|
413
|
+
});
|
|
414
|
+
}
|
|
415
|
+
for (const [userId, nodes] of Object.entries(nodesToUpdateRights)) {
|
|
416
|
+
finishInput.push(...nodes.map((node) => ({
|
|
417
|
+
userId,
|
|
418
|
+
rights: node.rights,
|
|
419
|
+
nodes: [
|
|
420
|
+
{
|
|
421
|
+
id: node.nodeId,
|
|
422
|
+
nameKey: null,
|
|
423
|
+
data: [],
|
|
424
|
+
},
|
|
425
|
+
],
|
|
426
|
+
})));
|
|
427
|
+
}
|
|
428
|
+
const subState = await this.#apiClient.cloud.shareNodeFinish.mutate(finishInput);
|
|
362
429
|
const currentProgress = Math.min((index + 1) * maxNodesBatchSize, totalNodesToShare);
|
|
363
430
|
progress?.({
|
|
364
431
|
total: totalNodesToShare,
|
|
365
432
|
current: currentProgress,
|
|
366
|
-
percent:
|
|
433
|
+
percent: currentProgress / totalNodesToShare,
|
|
367
434
|
});
|
|
368
435
|
return {
|
|
369
436
|
missingNodeAccesses: [
|
|
@@ -584,10 +651,11 @@ export class SecrecyCloudClient {
|
|
|
584
651
|
const others = node.parent?.users.filter(([u]) => u.id !== this.#client.app.userId) ??
|
|
585
652
|
[];
|
|
586
653
|
if (others.length > 0) {
|
|
587
|
-
await this.shareNode({
|
|
654
|
+
await this.shareNode(others.map(([user, rights]) => ({
|
|
655
|
+
userId: user.id,
|
|
656
|
+
rights,
|
|
588
657
|
nodeId: node.id,
|
|
589
|
-
|
|
590
|
-
});
|
|
658
|
+
})));
|
|
591
659
|
}
|
|
592
660
|
}
|
|
593
661
|
return node;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ProgressCallback, SecrecyClient } from '../index.js';
|
|
2
|
-
import type { DataMetadata, DataStorageType, KeyPair, LocalData, Node, NodeFull, NodeType
|
|
2
|
+
import type { DataMetadata, DataStorageType, KeyPair, LocalData, Node, NodeFull, NodeType } from './types/index.js';
|
|
3
3
|
import { type RouterInputs, type ApiClient, type RouterOutputs } from '../client.js';
|
|
4
4
|
import { type DownloadProgress } from '../types.js';
|
|
5
5
|
import { FileTypeResult } from 'file-type';
|
|
@@ -54,28 +54,7 @@ export declare class SecrecyCloudClient {
|
|
|
54
54
|
dataMetadata({ id }: {
|
|
55
55
|
id: string;
|
|
56
56
|
}): Promise<DataMetadata>;
|
|
57
|
-
shareNode(input:
|
|
58
|
-
rights: Rights;
|
|
59
|
-
nodes: {
|
|
60
|
-
nodeId: string;
|
|
61
|
-
userId: string;
|
|
62
|
-
}[] | {
|
|
63
|
-
nodeId: string;
|
|
64
|
-
userIds: string[];
|
|
65
|
-
} | {
|
|
66
|
-
nodeIds: string[];
|
|
67
|
-
userId: string;
|
|
68
|
-
} | {
|
|
69
|
-
nodeIds: string[];
|
|
70
|
-
userIds: string[];
|
|
71
|
-
};
|
|
72
|
-
} | {
|
|
73
|
-
nodeId: string;
|
|
74
|
-
users: {
|
|
75
|
-
id: string;
|
|
76
|
-
rights: Rights;
|
|
77
|
-
}[];
|
|
78
|
-
}, progress?: ProgressCallback): Promise<RouterOutputs['cloud']['shareNodeFinish']>;
|
|
57
|
+
shareNode(input: RouterInputs['cloud']['shareNode'], progress?: ProgressCallback): Promise<RouterOutputs['cloud']['shareNodeFinish']>;
|
|
79
58
|
updateNode({ nodeId, name, isFavorite, deletedAt, }: {
|
|
80
59
|
nodeId: string;
|
|
81
60
|
name?: string | null | undefined;
|
package/dist/types/client.d.ts
CHANGED
|
@@ -5912,32 +5912,46 @@ export declare const createTRPCClient: (opts: CreateTrpcClientOptions) => {
|
|
|
5912
5912
|
_ctx_out: {};
|
|
5913
5913
|
_input_in: {
|
|
5914
5914
|
userId: string;
|
|
5915
|
+
rights: "admin" | "write" | "read";
|
|
5915
5916
|
nodeId: string;
|
|
5916
5917
|
}[] | {
|
|
5918
|
+
rights: "admin" | "write" | "read";
|
|
5917
5919
|
userIds: string[];
|
|
5918
5920
|
nodeIds: string[];
|
|
5919
5921
|
} | {
|
|
5922
|
+
rights: "admin" | "write" | "read";
|
|
5920
5923
|
nodeId: string;
|
|
5921
5924
|
userIds: string[];
|
|
5922
5925
|
} | {
|
|
5923
5926
|
userId: string;
|
|
5927
|
+
rights: "admin" | "write" | "read";
|
|
5924
5928
|
nodeIds: string[];
|
|
5925
5929
|
};
|
|
5926
5930
|
_input_out: {
|
|
5927
5931
|
userId: string;
|
|
5932
|
+
rights: "admin" | "write" | "read";
|
|
5928
5933
|
nodeId: string;
|
|
5929
5934
|
}[] | {
|
|
5935
|
+
rights: "admin" | "write" | "read";
|
|
5930
5936
|
userIds: string[];
|
|
5931
5937
|
nodeIds: string[];
|
|
5932
5938
|
} | {
|
|
5939
|
+
rights: "admin" | "write" | "read";
|
|
5933
5940
|
nodeId: string;
|
|
5934
5941
|
userIds: string[];
|
|
5935
5942
|
} | {
|
|
5936
5943
|
userId: string;
|
|
5944
|
+
rights: "admin" | "write" | "read";
|
|
5937
5945
|
nodeIds: string[];
|
|
5938
5946
|
};
|
|
5939
|
-
_output_in: Record<string,
|
|
5940
|
-
|
|
5947
|
+
_output_in: Record<string, {
|
|
5948
|
+
nodeId: string;
|
|
5949
|
+
includeKeys: boolean;
|
|
5950
|
+
}[]>;
|
|
5951
|
+
_output_out: Record<string, {
|
|
5952
|
+
nodeId: string;
|
|
5953
|
+
includeKeys: boolean;
|
|
5954
|
+
}[]>;
|
|
5941
5955
|
}, unknown>>;
|
|
5942
5956
|
};
|
|
5943
5957
|
updateNode: {
|
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.62.0-feat-node-sharing.
|
|
5
|
+
"version": "1.62.0-feat-node-sharing.10",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
8
8
|
"url": "https://github.com/anonymize-org/lib.git"
|
|
@@ -74,7 +74,7 @@
|
|
|
74
74
|
"typescript": "^5.7.2"
|
|
75
75
|
},
|
|
76
76
|
"dependencies": {
|
|
77
|
-
"@secrecy/trpc-api-types": "1.33.0-feat-share-node-enhanced.
|
|
77
|
+
"@secrecy/trpc-api-types": "1.33.0-feat-share-node-enhanced.20",
|
|
78
78
|
"@trpc/client": "10.45.2",
|
|
79
79
|
"@trpc/server": "10.45.2",
|
|
80
80
|
"@types/libsodium-wrappers-sumo": "^0.7.8",
|