@secrecy/lib 1.65.0-feat-next15.3 → 1.65.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.
@@ -1,3 +1,4 @@
1
+ import axios from 'axios';
1
2
  import ky from 'ky';
2
3
  import { nodesCache, dataCache, dataContentCache, nodesEncryptionCache, } from '../cache.js';
3
4
  import { secretStreamKeygen } from '../crypto/data.js';
@@ -184,7 +185,7 @@ export class SecrecyCloudClient {
184
185
  const progressParts = {};
185
186
  const onProgress = (part, progressEvent) => {
186
187
  progressParts[part] = progressEvent;
187
- const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.transferredBytes, 0);
188
+ const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.loaded, 0);
188
189
  void uploadProgress?.({
189
190
  percent: current / encryptedData.byteLength,
190
191
  total: encryptedData.byteLength,
@@ -200,13 +201,12 @@ export class SecrecyCloudClient {
200
201
  for (const [key, value] of Object.entries(part.fields)) {
201
202
  formData.append(key, value);
202
203
  }
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,
204
+ formData.append('file', new Blob([chunk.data], { type: filetype?.mime }), `${uploadData.id}-${chunk.order}`);
205
+ await axios.post(part.url, formData, {
207
206
  onUploadProgress: (progressEvent) => {
208
207
  onProgress(part.order, progressEvent);
209
208
  },
209
+ signal,
210
210
  });
211
211
  return uploadDataPartEnd(chunk.md5, chunk.order);
212
212
  };
@@ -412,7 +412,7 @@ export class SecrecyCloudClient {
412
412
  .map((node) => {
413
413
  const share = shares.find((share) => share.nodeId === node.nodeId && share.userId === userId);
414
414
  if (!share) {
415
- throw new Error('Unable to retrieve rights!');
415
+ throw new Error('Unable to retrieve permissions!');
416
416
  }
417
417
  return {
418
418
  nodeId: node.nodeId,
@@ -424,12 +424,22 @@ export class SecrecyCloudClient {
424
424
  const withKeys = Object.fromEntries(Object.entries(infos).map('rights' in input
425
425
  ? ([userId, nodes]) => [
426
426
  userId,
427
- { userId, nodes, permissions: input },
427
+ {
428
+ userId,
429
+ nodes,
430
+ permissions: {
431
+ rights: input.rights,
432
+ addAccess: input.addAccess,
433
+ delAccess: input.delAccess,
434
+ sharingAddAccess: input.sharingAddAccess,
435
+ sharingDelAccess: input.sharingDelAccess,
436
+ },
437
+ },
428
438
  ]
429
439
  : ([userId, nodes]) => {
430
440
  const share = shares.find((share) => share.userId === userId && share.nodeId === nodes[0].id);
431
441
  if (!share) {
432
- throw new Error('Unable to retrieve rights!');
442
+ throw new Error('Unable to retrieve permissions!');
433
443
  }
434
444
  return [
435
445
  userId,
@@ -442,12 +452,12 @@ export class SecrecyCloudClient {
442
452
  userId,
443
453
  nodes: nodes.nodes.map((node) => ({
444
454
  id: node.id,
445
- ...nodes.permissions,
446
455
  nameKey: node.nameKey,
447
456
  data: node.data.map((d) => ({
448
457
  id: d.id,
449
458
  key: d.key,
450
459
  })),
460
+ ...nodes.permissions,
451
461
  })),
452
462
  });
453
463
  }
@@ -685,13 +695,14 @@ export class SecrecyCloudClient {
685
695
  });
686
696
  const node = await apiNodeToExternalNodeFull(saveInCloud, this.#keys);
687
697
  const me = node.parent?.users.find(([u]) => u.id === this.#client.app.userId);
688
- // TODO: Rights
689
- if (me !== undefined && ['admin', 'write'].includes(me[1]['rights'])) {
698
+ // TODO: ??
699
+ if (me !== undefined && ['delete', 'write'].includes(me[1].rights)) {
690
700
  const others = node.parent?.users.filter(([u]) => u.id !== this.#client.app.userId) ??
691
701
  [];
692
702
  if (others.length > 0) {
693
703
  await this.shareNode(others.map(([user, permissions]) => ({
694
704
  userId: user.id,
705
+ permissions,
695
706
  nodeId: node.id,
696
707
  ...permissions,
697
708
  })));
@@ -715,9 +726,7 @@ export class SecrecyCloudClient {
715
726
  }
716
727
  // Retrieve and format nodes.
717
728
  for (const nodeId of nodeIds) {
718
- let node;
719
- node ??= nodesEncryptionCache.get(nodeId);
720
- node ??= nodesCache.get(nodeId);
729
+ let node = nodesEncryptionCache.get(nodeId) ?? nodesCache.get(nodeId);
721
730
  if (node &&
722
731
  'history' in node &&
723
732
  node.history.length > 0 &&
@@ -66,8 +66,12 @@ function internalNodeToNode(internal) {
66
66
  })),
67
67
  access: {
68
68
  isRoot: internal.access.isRoot,
69
- rights: internal.access.rights,
70
69
  sharedByPubKey: internal.access.sharedByPubKey,
70
+ rights: internal.access.rights,
71
+ addAccess: internal.access.addAccess,
72
+ delAccess: internal.access.delAccess,
73
+ sharingAddAccess: internal.access.sharingAddAccess,
74
+ sharingDelAccess: internal.access.sharingDelAccess,
71
75
  },
72
76
  };
73
77
  return node;
@@ -1,10 +1,16 @@
1
- import { httpBatchLink, loggerLink, createTRPCClient as innerCreateTRPCClient, TRPCClientError, } from '@trpc/client';
1
+ import { httpBatchLink, loggerLink, createTRPCProxyClient, TRPCClientError, } from '@trpc/client';
2
+ import superjson from 'superjson';
2
3
  import { SECRECY_LIB_VERSION } from './versioning.js';
3
- import { transformer } from './transformer.js';
4
4
  export function isTRPCClientError(cause) {
5
5
  return cause instanceof TRPCClientError;
6
6
  }
7
- export const createTRPCClient = (opts) => innerCreateTRPCClient({
7
+ superjson.registerCustom({
8
+ isApplicable: (v) => v instanceof Buffer,
9
+ serialize: (v) => [...v],
10
+ deserialize: (v) => Buffer.from(v),
11
+ }, 'buffer');
12
+ export const createTRPCClient = (opts) => createTRPCProxyClient({
13
+ transformer: superjson,
8
14
  links: [
9
15
  loggerLink({
10
16
  enabled: (op) => {
@@ -18,7 +24,6 @@ export const createTRPCClient = (opts) => innerCreateTRPCClient({
18
24
  },
19
25
  }),
20
26
  httpBatchLink({
21
- transformer,
22
27
  url: opts.apiUrl
23
28
  ? `${opts.apiUrl}/trpc`
24
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
- firstname: string;
8
- lastname: string;
9
7
  id: string;
8
+ lastname: string;
9
+ firstname: 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 Progress } from '../types.js';
4
+ import { type DownloadProgress } 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: Progress) => void;
66
+ onDownloadProgress?: (progress: DownloadProgress) => 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: Progress) => void;
72
+ onDownloadProgress?: (progress: DownloadProgress) => void;
73
73
  progressDecrypt?: ProgressCallback;
74
74
  signal?: AbortSignal;
75
75
  }): Promise<LocalData[]>;
@@ -104,23 +104,22 @@ export declare class SecrecyCloudClient {
104
104
  toType: "s3" | "cold" | "lite";
105
105
  }>;
106
106
  getPublicDataLink(input: RouterInputs['cloud']['dataLink']): Promise<{
107
- id: string;
108
107
  name: string;
109
- slug: string;
110
- expireAt: Date | null;
108
+ id: string;
111
109
  dataId: string;
110
+ expireAt: Date | null;
111
+ slug: string;
112
112
  }>;
113
113
  getPublicDataLinks(input: RouterInputs['cloud']['dataLinks']): Promise<{
114
- id: string;
115
114
  name: string;
116
- slug: string;
117
- expireAt: Date | null;
115
+ id: string;
118
116
  dataId: string;
117
+ expireAt: Date | null;
118
+ slug: string;
119
119
  }[]>;
120
120
  checkAccesses(input: RouterInputs['cloud']['checkAccesses']): Promise<{
121
121
  isMatching: true;
122
122
  } | {
123
- isMatching: false;
124
123
  details: {
125
124
  missingNodeAccesses: {
126
125
  userId: string;
@@ -128,51 +127,52 @@ export declare class SecrecyCloudClient {
128
127
  }[];
129
128
  missingDataAccesses: {
130
129
  userId: string;
131
- nodeId: string;
132
130
  dataId: string;
131
+ nodeId: string;
133
132
  }[];
134
133
  invalidRightsAccesses: {
135
134
  userId: string;
136
- nodeId: string;
137
- expect: {
138
- rights: "delete" | "read" | "write";
135
+ current: {
136
+ rights: "delete" | "write" | "read";
139
137
  } & {
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;
138
+ addAccess?: "delete" | "write" | "read" | null | undefined;
139
+ sharingAddAccess?: "delete" | "write" | "read" | null | undefined;
140
+ delAccess?: "delete" | "write" | "read" | null | undefined;
141
+ sharingDelAccess?: "delete" | "write" | "read" | null | undefined;
144
142
  };
145
- current: {
146
- rights: "delete" | "read" | "write";
143
+ nodeId: string;
144
+ expect: {
145
+ rights: "delete" | "write" | "read";
147
146
  } & {
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;
147
+ addAccess?: "delete" | "write" | "read" | null | undefined;
148
+ sharingAddAccess?: "delete" | "write" | "read" | null | undefined;
149
+ delAccess?: "delete" | "write" | "read" | null | undefined;
150
+ sharingDelAccess?: "delete" | "write" | "read" | null | undefined;
152
151
  };
153
152
  }[];
154
153
  };
154
+ isMatching: false;
155
155
  }>;
156
156
  createPublicDataLink(input: RouterInputs['cloud']['createDataLink']): Promise<{
157
- id: string;
158
157
  name: string;
159
- slug: string;
160
- expireAt: Date | null;
158
+ id: string;
161
159
  dataId: string;
160
+ expireAt: Date | null;
161
+ slug: string;
162
162
  }>;
163
163
  updatePublicDataLink(input: RouterInputs['cloud']['updateDataLink']): Promise<{
164
- id: string;
165
164
  name: string;
166
- slug: string;
167
- expireAt: Date | null;
165
+ id: string;
168
166
  dataId: string;
167
+ expireAt: Date | null;
168
+ slug: string;
169
169
  }>;
170
170
  deletePublicDataLink(input: RouterInputs['cloud']['deleteDataLink']): Promise<{
171
- id: string;
172
171
  name: string;
173
- slug: string;
174
- expireAt: Date | null;
172
+ id: string;
175
173
  dataId: string;
174
+ expireAt: Date | null;
175
+ slug: string;
176
176
  }>;
177
177
  private _handleDataContent;
178
178
  }
@@ -1,5 +1,5 @@
1
1
  import { BaseClient, type SecrecyUrls } from '../base-client.js';
2
- import type { SecretStreamProgress } from '../crypto/data.js';
2
+ import type { Progress } 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: SecretStreamProgress) => Promise<void>;
14
+ export type ProgressCallback = (progress: Progress) => Promise<void>;
15
15
  export interface SecrecyClientOptions {
16
16
  uaSession: string;
17
17
  uaKeys: KeyPair;
@@ -7,14 +7,40 @@ export type * from './user.js';
7
7
  declare const keyPair: z.ZodObject<{
8
8
  publicKey: z.ZodString;
9
9
  privateKey: z.ZodString;
10
- }, z.core.$strict>;
10
+ }, "strict", z.ZodTypeAny, {
11
+ publicKey: string;
12
+ privateKey: string;
13
+ }, {
14
+ publicKey: string;
15
+ privateKey: string;
16
+ }>;
11
17
  export type KeyPair = z.infer<typeof keyPair>;
12
18
  export declare const secrecyUserApp: z.ZodReadonly<z.ZodObject<{
13
19
  keys: z.ZodObject<{
14
20
  publicKey: z.ZodString;
15
21
  privateKey: z.ZodString;
16
- }, z.core.$strict>;
22
+ }, "strict", z.ZodTypeAny, {
23
+ publicKey: string;
24
+ privateKey: string;
25
+ }, {
26
+ publicKey: string;
27
+ privateKey: string;
28
+ }>;
17
29
  jwt: z.ZodString;
18
30
  uaSession: z.ZodString;
19
- }, z.core.$strict>>;
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
+ }>>;
20
46
  export type SecrecyUserApp = z.infer<typeof secrecyUserApp>;
@@ -1,8 +1,8 @@
1
1
  import { type RouterOutputs } from '../../client.js';
2
2
  import type { DataMetadata, InternalData, PublicUser } from './index.js';
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 & {
3
+ export type Permissions = ApiNode['users'][number][1];
4
+ export type Rights = Permissions['rights'];
5
+ export type NodeAccess<T extends Record<string, unknown> = Record<string, unknown>> = T & Permissions & {
6
6
  isRoot: boolean;
7
7
  sharedByPubKey: string;
8
8
  };
@@ -33,7 +33,7 @@ export interface Node<T extends NodeBreadcrumbItem = NodeBreadcrumbItem, U exten
33
33
  breadcrumb: T[];
34
34
  owner: PublicUser;
35
35
  access: NodeAccess<U>;
36
- users: Array<[PublicUser, NodePermissions]>;
36
+ users: Array<[PublicUser, Permissions]>;
37
37
  currentDataId: string | null;
38
38
  parentId: string | null;
39
39
  }
@@ -82,9 +82,9 @@ export type ShareNodeDetails = {
82
82
  }[];
83
83
  invalidRightsAccesses: {
84
84
  userId: string;
85
- current: NodePermissions;
85
+ current: Permissions;
86
86
  nodeId: string;
87
- expect: NodePermissions;
87
+ expect: Permissions;
88
88
  }[];
89
89
  };
90
90
  export {};