@secrecy/lib 1.64.1-feat-share-up-to.1 → 1.65.0-feat-next15.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.
@@ -1,4 +1,3 @@
1
- import axios from 'axios';
2
1
  import ky from 'ky';
3
2
  import { nodesCache, dataCache, dataContentCache, nodesEncryptionCache, } from '../cache.js';
4
3
  import { secretStreamKeygen } from '../crypto/data.js';
@@ -185,7 +184,7 @@ export class SecrecyCloudClient {
185
184
  const progressParts = {};
186
185
  const onProgress = (part, progressEvent) => {
187
186
  progressParts[part] = progressEvent;
188
- const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.loaded, 0);
187
+ const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.transferredBytes, 0);
189
188
  void uploadProgress?.({
190
189
  percent: current / encryptedData.byteLength,
191
190
  total: encryptedData.byteLength,
@@ -201,12 +200,13 @@ export class SecrecyCloudClient {
201
200
  for (const [key, value] of Object.entries(part.fields)) {
202
201
  formData.append(key, value);
203
202
  }
204
- formData.append('file', new Blob([chunk.data], { type: filetype?.mime }), `${uploadData.id}-${chunk.order}`);
205
- await axios.post(part.url, formData, {
203
+ formData.append('file', new Blob([chunk.data.slice(0)], { type: filetype?.mime }), `${uploadData.id}-${chunk.order}`);
204
+ await ky.post(part.url, {
205
+ signal,
206
+ body: formData,
206
207
  onUploadProgress: (progressEvent) => {
207
208
  onProgress(part.order, progressEvent);
208
209
  },
209
- signal,
210
210
  });
211
211
  return uploadDataPartEnd(chunk.md5, chunk.order);
212
212
  };
@@ -308,7 +308,11 @@ export class SecrecyCloudClient {
308
308
  await this.shareNode(users.map(([user, permissions]) => ({
309
309
  userId: user.id,
310
310
  nodeId: folder.id,
311
- permissions,
311
+ rights: permissions.rights,
312
+ addAccess: permissions.addAccess,
313
+ delAccess: permissions.delAccess,
314
+ sharingAddAccess: permissions.sharingAddAccess,
315
+ sharingDelAccess: permissions.sharingDelAccess,
312
316
  })));
313
317
  }
314
318
  return folder;
@@ -355,21 +359,49 @@ export class SecrecyCloudClient {
355
359
  .filter((entry) => entry !== null));
356
360
  const infos = await this.encryptNodesForUsers(nodesToEncrypt, publicKeysMap);
357
361
  const shares = Array.isArray(input)
358
- ? input
362
+ ? input.map((opt) => ({
363
+ nodeId: opt.nodeId,
364
+ userId: opt.userId,
365
+ permissions: {
366
+ rights: opt.rights,
367
+ addAccess: opt.addAccess,
368
+ delAccess: opt.delAccess,
369
+ sharingAddAccess: opt.sharingAddAccess,
370
+ sharingDelAccess: opt.sharingDelAccess,
371
+ },
372
+ }))
359
373
  : 'userIds' in input
360
374
  ? 'nodeIds' in input
361
375
  ? input.userIds.flatMap((userId) => input.nodeIds.map((nodeId) => ({
362
- permissions: input.permissions,
376
+ permissions: {
377
+ rights: input.rights,
378
+ addAccess: input.addAccess,
379
+ delAccess: input.delAccess,
380
+ sharingAddAccess: input.sharingAddAccess,
381
+ sharingDelAccess: input.sharingDelAccess,
382
+ },
363
383
  userId,
364
384
  nodeId,
365
385
  })))
366
386
  : input.userIds.map((userId) => ({
367
- permissions: input.permissions,
387
+ permissions: {
388
+ rights: input.rights,
389
+ addAccess: input.addAccess,
390
+ delAccess: input.delAccess,
391
+ sharingAddAccess: input.sharingAddAccess,
392
+ sharingDelAccess: input.sharingDelAccess,
393
+ },
368
394
  userId,
369
395
  nodeId: input.nodeId,
370
396
  }))
371
397
  : input.nodeIds.map((nodeId) => ({
372
- permissions: input.permissions,
398
+ permissions: {
399
+ rights: input.rights,
400
+ addAccess: input.addAccess,
401
+ delAccess: input.delAccess,
402
+ sharingAddAccess: input.sharingAddAccess,
403
+ sharingDelAccess: input.sharingDelAccess,
404
+ },
373
405
  nodeId,
374
406
  userId: input.userId,
375
407
  }));
@@ -380,7 +412,7 @@ export class SecrecyCloudClient {
380
412
  .map((node) => {
381
413
  const share = shares.find((share) => share.nodeId === node.nodeId && share.userId === userId);
382
414
  if (!share) {
383
- throw new Error('Unable to retrieve permissions!');
415
+ throw new Error('Unable to retrieve rights!');
384
416
  }
385
417
  return {
386
418
  nodeId: node.nodeId,
@@ -389,15 +421,15 @@ export class SecrecyCloudClient {
389
421
  };
390
422
  }),
391
423
  ]));
392
- const withKeys = Object.fromEntries(Object.entries(infos).map('permissions' in input
424
+ const withKeys = Object.fromEntries(Object.entries(infos).map('rights' in input
393
425
  ? ([userId, nodes]) => [
394
426
  userId,
395
- { userId, nodes, permissions: input.permissions },
427
+ { userId, nodes, permissions: input },
396
428
  ]
397
429
  : ([userId, nodes]) => {
398
430
  const share = shares.find((share) => share.userId === userId && share.nodeId === nodes[0].id);
399
431
  if (!share) {
400
- throw new Error('Unable to retrieve permissions!');
432
+ throw new Error('Unable to retrieve rights!');
401
433
  }
402
434
  return [
403
435
  userId,
@@ -410,7 +442,7 @@ export class SecrecyCloudClient {
410
442
  userId,
411
443
  nodes: nodes.nodes.map((node) => ({
412
444
  id: node.id,
413
- permissions: nodes.permissions,
445
+ ...nodes.permissions,
414
446
  nameKey: node.nameKey,
415
447
  data: node.data.map((d) => ({
416
448
  id: d.id,
@@ -425,8 +457,8 @@ export class SecrecyCloudClient {
425
457
  nodes: [
426
458
  {
427
459
  id: node.nodeId,
428
- permissions: node.permissions,
429
460
  data: [],
461
+ ...node.permissions,
430
462
  },
431
463
  ],
432
464
  })));
@@ -653,15 +685,15 @@ export class SecrecyCloudClient {
653
685
  });
654
686
  const node = await apiNodeToExternalNodeFull(saveInCloud, this.#keys);
655
687
  const me = node.parent?.users.find(([u]) => u.id === this.#client.app.userId);
656
- // TODO: ??
657
- if (me !== undefined && ['delete', 'write'].includes(me[1].rights)) {
688
+ // TODO: Rights
689
+ if (me !== undefined && ['admin', 'write'].includes(me[1]['rights'])) {
658
690
  const others = node.parent?.users.filter(([u]) => u.id !== this.#client.app.userId) ??
659
691
  [];
660
692
  if (others.length > 0) {
661
693
  await this.shareNode(others.map(([user, permissions]) => ({
662
694
  userId: user.id,
663
- permissions,
664
695
  nodeId: node.id,
696
+ ...permissions,
665
697
  })));
666
698
  }
667
699
  }
@@ -25,7 +25,6 @@ async function apiNodeToInternal(apiNode, keyPair) {
25
25
  parentId: apiNode.parentId ?? null,
26
26
  currentDataId: apiNode.currentDataId ?? null,
27
27
  };
28
- internal.access = { ...apiNode.access };
29
28
  if (apiNode.access.nameKey !== null) {
30
29
  const key = decryptCryptoBox(sodium.from_hex(apiNode.access.nameKey), apiNode.access.sharedByPubKey, keyPair.privateKey);
31
30
  internal.name = sodium.to_string(await decryptSecretStream(key, sodium.from_hex(internal.name)));
@@ -67,8 +66,8 @@ function internalNodeToNode(internal) {
67
66
  })),
68
67
  access: {
69
68
  isRoot: internal.access.isRoot,
69
+ rights: internal.access.rights,
70
70
  sharedByPubKey: internal.access.sharedByPubKey,
71
- permissions: internal.access.permissions,
72
71
  },
73
72
  };
74
73
  return node;
@@ -1,4 +1,4 @@
1
- import { httpBatchLink, loggerLink, createTRPCProxyClient, TRPCClientError, } from '@trpc/client';
1
+ import { httpBatchLink, loggerLink, createTRPCClient as innerCreateTRPCClient, TRPCClientError, } from '@trpc/client';
2
2
  import superjson from 'superjson';
3
3
  import { SECRECY_LIB_VERSION } from './versioning.js';
4
4
  export function isTRPCClientError(cause) {
@@ -9,8 +9,7 @@ superjson.registerCustom({
9
9
  serialize: (v) => [...v],
10
10
  deserialize: (v) => Buffer.from(v),
11
11
  }, 'buffer');
12
- export const createTRPCClient = (opts) => createTRPCProxyClient({
13
- transformer: superjson,
12
+ export const createTRPCClient = (opts) => innerCreateTRPCClient({
14
13
  links: [
15
14
  loggerLink({
16
15
  enabled: (op) => {
@@ -24,6 +23,7 @@ export const createTRPCClient = (opts) => createTRPCProxyClient({
24
23
  },
25
24
  }),
26
25
  httpBatchLink({
26
+ transformer: superjson,
27
27
  url: opts.apiUrl
28
28
  ? `${opts.apiUrl}/trpc`
29
29
  : 'https://api.secrecy.tech/trpc',
@@ -4,9 +4,9 @@ export declare const dataCache: Map<string, InternalData>;
4
4
  export declare const nodesCache: Map<string, InternalNode | InternalNodeFull>;
5
5
  export declare const nodesEncryptionCache: Map<string, InternalMinimalNodeForEncryption>;
6
6
  export declare const usersCache: Map<string, {
7
- id: string;
8
- lastname: string;
9
7
  firstname: string;
8
+ lastname: string;
9
+ id: string;
10
10
  avatar: string | null;
11
11
  isSearchable: boolean;
12
12
  }>;
@@ -1,7 +1,7 @@
1
1
  import type { ProgressCallback, SecrecyClient } from '../index.js';
2
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
- import { type DownloadProgress } from '../types.js';
4
+ import { type Progress } from '../types.js';
5
5
  import { FileTypeResult } from 'file-type';
6
6
  export declare class SecrecyCloudClient {
7
7
  #private;
@@ -63,13 +63,13 @@ export declare class SecrecyCloudClient {
63
63
  }): Promise<NodeFull>;
64
64
  dataContent({ dataId, onDownloadProgress, progressDecrypt, signal, }: {
65
65
  dataId: string;
66
- onDownloadProgress?: (progress: DownloadProgress) => void;
66
+ onDownloadProgress?: (progress: Progress) => void;
67
67
  progressDecrypt?: ProgressCallback;
68
68
  signal?: AbortSignal;
69
69
  }): Promise<LocalData>;
70
70
  dataContents({ dataIds, onDownloadProgress, progressDecrypt, signal, }: {
71
71
  dataIds: string[];
72
- onDownloadProgress?: (progress: DownloadProgress) => void;
72
+ onDownloadProgress?: (progress: Progress) => void;
73
73
  progressDecrypt?: ProgressCallback;
74
74
  signal?: AbortSignal;
75
75
  }): Promise<LocalData[]>;
@@ -104,22 +104,23 @@ export declare class SecrecyCloudClient {
104
104
  toType: "s3" | "cold" | "lite";
105
105
  }>;
106
106
  getPublicDataLink(input: RouterInputs['cloud']['dataLink']): Promise<{
107
- name: string;
108
107
  id: string;
109
- dataId: string;
110
- expireAt: Date | null;
108
+ name: string;
111
109
  slug: string;
110
+ expireAt: Date | null;
111
+ dataId: string;
112
112
  }>;
113
113
  getPublicDataLinks(input: RouterInputs['cloud']['dataLinks']): Promise<{
114
- name: string;
115
114
  id: string;
116
- dataId: string;
117
- expireAt: Date | null;
115
+ name: string;
118
116
  slug: string;
117
+ expireAt: Date | null;
118
+ dataId: string;
119
119
  }[]>;
120
120
  checkAccesses(input: RouterInputs['cloud']['checkAccesses']): Promise<{
121
121
  isMatching: true;
122
122
  } | {
123
+ isMatching: false;
123
124
  details: {
124
125
  missingNodeAccesses: {
125
126
  userId: string;
@@ -127,50 +128,51 @@ export declare class SecrecyCloudClient {
127
128
  }[];
128
129
  missingDataAccesses: {
129
130
  userId: string;
130
- dataId: string;
131
131
  nodeId: string;
132
+ dataId: string;
132
133
  }[];
133
134
  invalidRightsAccesses: {
134
135
  userId: string;
135
- current: {
136
- rights: "delete" | "write" | "read";
137
- addAccess: "delete" | "write" | "read" | null;
138
- sharingAddAccess: "delete" | "write" | "read" | null;
139
- delAccess: "delete" | "write" | "read" | null;
140
- sharingDelAccess: "delete" | "write" | "read" | null;
141
- };
142
136
  nodeId: string;
143
137
  expect: {
144
- rights: "delete" | "write" | "read";
145
- addAccess: "delete" | "write" | "read" | null;
146
- sharingAddAccess: "delete" | "write" | "read" | null;
147
- delAccess: "delete" | "write" | "read" | null;
148
- sharingDelAccess: "delete" | "write" | "read" | null;
138
+ rights: "delete" | "read" | "write";
139
+ } & {
140
+ addAccess?: "delete" | "read" | "write" | null | undefined;
141
+ sharingAddAccess?: "delete" | "read" | "write" | null | undefined;
142
+ delAccess?: "delete" | "read" | "write" | null | undefined;
143
+ sharingDelAccess?: "delete" | "read" | "write" | null | undefined;
144
+ };
145
+ current: {
146
+ rights: "delete" | "read" | "write";
147
+ } & {
148
+ addAccess?: "delete" | "read" | "write" | null | undefined;
149
+ sharingAddAccess?: "delete" | "read" | "write" | null | undefined;
150
+ delAccess?: "delete" | "read" | "write" | null | undefined;
151
+ sharingDelAccess?: "delete" | "read" | "write" | null | undefined;
149
152
  };
150
153
  }[];
151
154
  };
152
- isMatching: false;
153
155
  }>;
154
156
  createPublicDataLink(input: RouterInputs['cloud']['createDataLink']): Promise<{
155
- name: string;
156
157
  id: string;
157
- dataId: string;
158
- expireAt: Date | null;
158
+ name: string;
159
159
  slug: string;
160
+ expireAt: Date | null;
161
+ dataId: string;
160
162
  }>;
161
163
  updatePublicDataLink(input: RouterInputs['cloud']['updateDataLink']): Promise<{
162
- name: string;
163
164
  id: string;
164
- dataId: string;
165
- expireAt: Date | null;
165
+ name: string;
166
166
  slug: string;
167
+ expireAt: Date | null;
168
+ dataId: string;
167
169
  }>;
168
170
  deletePublicDataLink(input: RouterInputs['cloud']['deleteDataLink']): Promise<{
169
- name: string;
170
171
  id: string;
171
- dataId: string;
172
- expireAt: Date | null;
172
+ name: string;
173
173
  slug: string;
174
+ expireAt: Date | null;
175
+ dataId: string;
174
176
  }>;
175
177
  private _handleDataContent;
176
178
  }
@@ -1,5 +1,5 @@
1
1
  import { BaseClient, type SecrecyUrls } from '../base-client.js';
2
- import type { Progress } from '../crypto/data.js';
2
+ import type { SecretStreamProgress } from '../crypto/data.js';
3
3
  import { SecrecyCloudClient } from './SecrecyCloudClient.js';
4
4
  import { SecrecyMailClient } from './SecrecyMailClient.js';
5
5
  import { SecrecyAppClient } from './SecrecyAppClient.js';
@@ -11,7 +11,7 @@ import { type KeyPair } from './types/index.js';
11
11
  import { SecrecyUserClient } from './SecrecyUserClient.js';
12
12
  import { SecrecyPseudonymClient } from './SecrecyPseudonymClient.js';
13
13
  export type NewMail = Pick<RouterInputs['mail']['createDraft'], 'body' | 'subject' | 'senderFiles' | 'recipients' | 'replyToId'>;
14
- export type ProgressCallback = (progress: Progress) => Promise<void>;
14
+ export type ProgressCallback = (progress: SecretStreamProgress) => Promise<void>;
15
15
  export interface SecrecyClientOptions {
16
16
  uaSession: string;
17
17
  uaKeys: KeyPair;
@@ -7,40 +7,14 @@ export type * from './user.js';
7
7
  declare const keyPair: z.ZodObject<{
8
8
  publicKey: z.ZodString;
9
9
  privateKey: z.ZodString;
10
- }, "strict", z.ZodTypeAny, {
11
- publicKey: string;
12
- privateKey: string;
13
- }, {
14
- publicKey: string;
15
- privateKey: string;
16
- }>;
10
+ }, z.core.$strict>;
17
11
  export type KeyPair = z.infer<typeof keyPair>;
18
12
  export declare const secrecyUserApp: z.ZodReadonly<z.ZodObject<{
19
13
  keys: z.ZodObject<{
20
14
  publicKey: z.ZodString;
21
15
  privateKey: z.ZodString;
22
- }, "strict", z.ZodTypeAny, {
23
- publicKey: string;
24
- privateKey: string;
25
- }, {
26
- publicKey: string;
27
- privateKey: string;
28
- }>;
16
+ }, z.core.$strict>;
29
17
  jwt: z.ZodString;
30
18
  uaSession: z.ZodString;
31
- }, "strict", z.ZodTypeAny, {
32
- keys: {
33
- publicKey: string;
34
- privateKey: string;
35
- };
36
- jwt: string;
37
- uaSession: string;
38
- }, {
39
- keys: {
40
- publicKey: string;
41
- privateKey: string;
42
- };
43
- jwt: string;
44
- uaSession: string;
45
- }>>;
19
+ }, z.core.$strict>>;
46
20
  export type SecrecyUserApp = z.infer<typeof secrecyUserApp>;
@@ -1,9 +1,8 @@
1
1
  import { type RouterOutputs } from '../../client.js';
2
2
  import type { DataMetadata, InternalData, PublicUser } from './index.js';
3
- export type NodeRights = ApiNode['users'][number][1];
4
- export type Permissions = Pick<ApiNode['access']['permissions'], 'rights'> & Partial<Omit<ApiNode['access']['permissions'], 'rights'>>;
5
- export type NodeAccess<T extends Record<string, unknown> = Record<string, unknown>> = T & {
6
- permissions: Permissions;
3
+ export type NodePermissions = ApiNode['users'][number][1];
4
+ export type Rights = NodePermissions['rights'];
5
+ export type NodeAccess<T extends Record<string, unknown> = Record<string, unknown>> = T & NodePermissions & {
7
6
  isRoot: boolean;
8
7
  sharedByPubKey: string;
9
8
  };
@@ -34,7 +33,7 @@ export interface Node<T extends NodeBreadcrumbItem = NodeBreadcrumbItem, U exten
34
33
  breadcrumb: T[];
35
34
  owner: PublicUser;
36
35
  access: NodeAccess<U>;
37
- users: Array<[PublicUser, NodeRights]>;
36
+ users: Array<[PublicUser, NodePermissions]>;
38
37
  currentDataId: string | null;
39
38
  parentId: string | null;
40
39
  }
@@ -83,9 +82,9 @@ export type ShareNodeDetails = {
83
82
  }[];
84
83
  invalidRightsAccesses: {
85
84
  userId: string;
86
- current: NodeRights;
85
+ current: NodePermissions;
87
86
  nodeId: string;
88
- expect: NodeRights;
87
+ expect: NodePermissions;
89
88
  }[];
90
89
  };
91
90
  export {};