@secrecy/lib 1.68.0-feat-anonymous-upload.2 → 1.68.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,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';
@@ -15,6 +14,7 @@ import { kiloToBytes } from '../utils.js';
15
14
  import { fileTypeFromBuffer } from 'file-type';
16
15
  import { encryptName, generateAndEncryptNameAndKey } from '../crypto/domain.js';
17
16
  import { chunkByTotalItems } from '../utils/object.js';
17
+ import axios from 'axios';
18
18
  export class SecrecyCloudClient {
19
19
  #client;
20
20
  #keys;
@@ -25,10 +25,7 @@ export class SecrecyCloudClient {
25
25
  this.#apiClient = apiClient;
26
26
  }
27
27
  async addDataToHistory({ dataId, nodeId, }) {
28
- const addDataToHistory = await this.#apiClient.cloud.addDataToHistory.mutate({
29
- dataId,
30
- nodeId,
31
- });
28
+ const addDataToHistory = await this.#apiClient.cloud.addDataToHistory.mutate({ dataId, nodeId });
32
29
  const node = await apiNodeFullToInternalFull(addDataToHistory, this.#keys);
33
30
  const data = node.history.find((d) => d.id === dataId);
34
31
  if (data !== undefined) {
@@ -74,10 +71,7 @@ export class SecrecyCloudClient {
74
71
  const dataKey = encrypted ? secretStreamKeygen() : null;
75
72
  const { data: encryptedData, md5: md5Data, md5Encrypted, } = dataKey
76
73
  ? await encrypt(dataKey, compressed, encryptProgress, signal)
77
- : {
78
- data: compressed,
79
- md5: await md5(compressed),
80
- };
74
+ : { data: compressed, md5: await md5(compressed) };
81
75
  const encryptedDataKey = dataKey
82
76
  ? encryptCryptoBox(dataKey, this.#keys.publicKey, this.#keys.privateKey)
83
77
  : null;
@@ -148,8 +142,7 @@ export class SecrecyCloudClient {
148
142
  signal,
149
143
  });
150
144
  if (uploadData.parts.length === 0) {
151
- if (uploadData.keyPair &&
152
- uploadData.keyPair.pub !== this.#keys.publicKey) {
145
+ if (uploadData.keyPair.pub !== this.#keys.publicKey) {
153
146
  throw new Error('The public key does not match with cached key!');
154
147
  }
155
148
  await uploadProgress?.({
@@ -169,11 +162,7 @@ export class SecrecyCloudClient {
169
162
  return localData;
170
163
  }
171
164
  const uploadDataPartEnd = async (md5, order) => {
172
- return this.#apiClient.cloud.uploadDataPartEnd.mutate({
173
- dataId: uploadData.id,
174
- md5,
175
- order,
176
- }, { signal });
165
+ return this.#apiClient.cloud.uploadDataPartEnd.mutate({ dataId: uploadData.id, md5, order }, { signal });
177
166
  };
178
167
  const chunkParts = new Array();
179
168
  for (const [index, chunk] of enumerate(chunks(encryptedData, Number(uploadData.partSize)))) {
@@ -186,7 +175,7 @@ export class SecrecyCloudClient {
186
175
  const progressParts = {};
187
176
  const onProgress = (part, progressEvent) => {
188
177
  progressParts[part] = progressEvent;
189
- const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.loaded, 0);
178
+ const current = Object.values(progressParts).reduce((prv, cur) => prv + cur.transferredBytes, 0);
190
179
  void uploadProgress?.({
191
180
  percent: current / encryptedData.byteLength,
192
181
  total: encryptedData.byteLength,
@@ -203,11 +192,21 @@ export class SecrecyCloudClient {
203
192
  formData.append(key, value);
204
193
  }
205
194
  formData.append('file', new Blob([chunk.data], { type: filetype?.mime }), `${uploadData.id}-${chunk.order}`);
195
+ // await ky.post(part.url, {
196
+ // signal,
197
+ // body: formData,
198
+ // onUploadProgress: (progressEvent) => {
199
+ // onProgress(part.order, progressEvent)
200
+ // },
201
+ // })
206
202
  await axios.post(part.url, formData, {
207
203
  onUploadProgress: (progressEvent) => {
208
- onProgress(part.order, progressEvent);
204
+ onProgress(part.order, {
205
+ percent: progressEvent.progress ?? 0,
206
+ totalBytes: progressEvent.total ?? 0,
207
+ transferredBytes: progressEvent.loaded,
208
+ });
209
209
  },
210
- signal,
211
210
  });
212
211
  return uploadDataPartEnd(chunk.md5, chunk.order);
213
212
  };
@@ -235,11 +234,7 @@ export class SecrecyCloudClient {
235
234
  uploadProgress,
236
235
  signal,
237
236
  });
238
- return await this.saveInCloud({
239
- dataId: uploadedData.id,
240
- name,
241
- nodeId,
242
- });
237
+ return await this.saveInCloud({ dataId: uploadedData.id, name, nodeId });
243
238
  }
244
239
  async deletedNodes() {
245
240
  const deletedNodes = await this.#apiClient.cloud.nodesDeleted.query({});
@@ -250,9 +245,7 @@ export class SecrecyCloudClient {
250
245
  return await Promise.all(nodesShared.map(async (node) => await apiNodeToExternal(node, this.#keys)));
251
246
  }
252
247
  async nodesSharedWithMe(type = 'FOLDER') {
253
- const nodesSharedWithMe = await this.#apiClient.cloud.nodesSharedWithMe.query({
254
- type,
255
- });
248
+ const nodesSharedWithMe = await this.#apiClient.cloud.nodesSharedWithMe.query({ type });
256
249
  return await Promise.all(nodesSharedWithMe.map(async (node) => await apiNodeToExternal(node, this.#keys)));
257
250
  }
258
251
  async deleteNodeSharing({ nodeId, userId, }) {
@@ -286,9 +279,7 @@ export class SecrecyCloudClient {
286
279
  return isDuplicated;
287
280
  }
288
281
  async deleteNodeCloudTrash({ ids }) {
289
- const { isDeleted } = await this.#apiClient.cloud.deleteNodeCloudTrash.mutate({
290
- ids,
291
- });
282
+ const { isDeleted } = await this.#apiClient.cloud.deleteNodeCloudTrash.mutate({ ids });
292
283
  return isDeleted;
293
284
  }
294
285
  async createFolder({ name, parentFolderId, }) {
@@ -319,16 +310,11 @@ export class SecrecyCloudClient {
319
310
  return folder;
320
311
  }
321
312
  async node({ id, deleted, } = {}) {
322
- const node = await this.#apiClient.cloud.nodeFullById.query({
323
- id,
324
- deleted,
325
- });
313
+ const node = await this.#apiClient.cloud.nodeFullById.query({ id, deleted });
326
314
  return await apiNodeToExternalNodeFull(node, this.#keys);
327
315
  }
328
316
  async dataMetadata({ id }) {
329
- const data = await this.#apiClient.cloud.dataById.query({
330
- id,
331
- });
317
+ const data = await this.#apiClient.cloud.dataById.query({ id });
332
318
  return apiDataToExternal(data, this.#keys);
333
319
  }
334
320
  async shareNode(input, progress) {
@@ -340,11 +326,7 @@ export class SecrecyCloudClient {
340
326
  const publicKeysMap = await this.#client.app.userPublicKey(neededUserKey);
341
327
  const maxNodesBatchSize = 1000;
342
328
  const totalNodesToShare = Object.values(nodesMap).reduce((size, ids) => size + ids.length, 0);
343
- progress?.({
344
- total: totalNodesToShare,
345
- current: 0,
346
- percent: 0,
347
- });
329
+ progress?.({ total: totalNodesToShare, current: 0, percent: 0 });
348
330
  const chunks = totalNodesToShare > maxNodesBatchSize
349
331
  ? chunkByTotalItems(nodesMap, maxNodesBatchSize)
350
332
  : [nodesMap];
@@ -465,13 +447,7 @@ export class SecrecyCloudClient {
465
447
  for (const [userId, nodes] of Object.entries(nodesToUpdateRights)) {
466
448
  finishInput.push(...nodes.map((node) => ({
467
449
  userId,
468
- nodes: [
469
- {
470
- id: node.nodeId,
471
- data: [],
472
- ...node.permissions,
473
- },
474
- ],
450
+ nodes: [{ id: node.nodeId, data: [], ...node.permissions }],
475
451
  })));
476
452
  }
477
453
  const subState = await this.#apiClient.cloud.shareNodeFinish.mutate(finishInput);
@@ -509,10 +485,7 @@ export class SecrecyCloudClient {
509
485
  const errorDetailsLength = details.invalidRightsAccesses.length +
510
486
  details.missingDataAccesses.length +
511
487
  details.missingNodeAccesses.length;
512
- return {
513
- isFinished: errorDetailsLength === 0,
514
- details: details,
515
- };
488
+ return { isFinished: errorDetailsLength === 0, details: details };
516
489
  }
517
490
  async updateNode({ nodeId, name, isFavorite, deletedAt, }) {
518
491
  let node = nodesCache.get(nodeId);
@@ -595,9 +568,7 @@ export class SecrecyCloudClient {
595
568
  }));
596
569
  }
597
570
  async deleteNodes({ nodeIds, }) {
598
- return this.#apiClient.cloud.deleteNodes.mutate({
599
- ids: nodeIds,
600
- });
571
+ return this.#apiClient.cloud.deleteNodes.mutate({ ids: nodeIds });
601
572
  }
602
573
  async deleteData({ dataId, nodeId, }) {
603
574
  const { isDeleted } = await this.#apiClient.cloud.deleteData.mutate({
@@ -1,16 +1,10 @@
1
- import { httpBatchLink, loggerLink, createTRPCProxyClient, TRPCClientError, } from '@trpc/client';
2
- import superjson from 'superjson';
1
+ import { httpBatchLink, loggerLink, createTRPCClient as innerCreateTRPCClient, TRPCClientError, } from '@trpc/client';
3
2
  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
- 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,
7
+ export const createTRPCClient = (opts) => innerCreateTRPCClient({
14
8
  links: [
15
9
  loggerLink({
16
10
  enabled: (op) => {
@@ -24,6 +18,7 @@ export const createTRPCClient = (opts) => createTRPCProxyClient({
24
18
  },
25
19
  }),
26
20
  httpBatchLink({
21
+ transformer,
27
22
  url: opts.apiUrl
28
23
  ? `${opts.apiUrl}/trpc`
29
24
  : 'https://api.secrecy.tech/trpc',
@@ -0,0 +1,18 @@
1
+ import { Temporal } from '@js-temporal/polyfill';
2
+ import superjson from 'superjson';
3
+ superjson.registerCustom({
4
+ isApplicable: (v) => v instanceof Temporal.PlainDate,
5
+ serialize: (v) => v.toJSON(),
6
+ deserialize: (v) => Temporal.PlainDate.from(v),
7
+ }, 'Temporal.PlainDate');
8
+ superjson.registerCustom({
9
+ isApplicable: (v) => v instanceof Temporal.PlainDateTime,
10
+ serialize: (v) => v.toJSON(),
11
+ deserialize: (v) => Temporal.PlainDateTime.from(v),
12
+ }, 'Temporal.PlainDateTime');
13
+ superjson.registerCustom({
14
+ isApplicable: (v) => v instanceof Buffer,
15
+ serialize: (v) => [...v],
16
+ deserialize: (v) => Buffer.from(v),
17
+ }, 'buffer');
18
+ export const transformer = superjson;
@@ -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;
@@ -12,7 +12,7 @@ export declare class SecrecyCloudClient {
12
12
  }): Promise<NodeFull>;
13
13
  uploadData({ storageType, data, encrypted, encryptProgress, uploadProgress, signal, meta, }: {
14
14
  storageType: DataStorageType;
15
- data: globalThis.File | Uint8Array;
15
+ data: globalThis.File | Uint8Array<ArrayBuffer>;
16
16
  encrypted?: boolean;
17
17
  encryptProgress?: ProgressCallback;
18
18
  uploadProgress?: ProgressCallback;
@@ -20,7 +20,7 @@ export declare class SecrecyCloudClient {
20
20
  meta?: FileTypeResult | true;
21
21
  }): Promise<LocalData>;
22
22
  uploadDataInCloud({ data, name, nodeId, encryptProgress, uploadProgress, storageType, signal, }: {
23
- data: globalThis.File | Uint8Array;
23
+ data: globalThis.File | Uint8Array<ArrayBuffer>;
24
24
  name: string;
25
25
  nodeId?: string;
26
26
  encryptProgress?: ProgressCallback;
@@ -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,21 +104,15 @@ 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
- createdByUserId: string | null;
110
- createdByAppId: string | null;
111
- createdByOrgId: string | null;
108
+ name: string;
112
109
  slug: string;
113
110
  expireAt: Date | null;
114
111
  dataId: string;
115
112
  }>;
116
113
  getPublicDataLinks(input: RouterInputs['cloud']['dataLinks']): Promise<{
117
- name: string;
118
114
  id: string;
119
- createdByUserId: string | null;
120
- createdByAppId: string | null;
121
- createdByOrgId: string | null;
115
+ name: string;
122
116
  slug: string;
123
117
  expireAt: Date | null;
124
118
  dataId: string;
@@ -126,6 +120,7 @@ export declare class SecrecyCloudClient {
126
120
  checkAccesses(input: RouterInputs['cloud']['checkAccesses']): Promise<{
127
121
  isMatching: true;
128
122
  } | {
123
+ isMatching: false;
129
124
  details: {
130
125
  missingNodeAccesses: {
131
126
  userId: string;
@@ -133,58 +128,48 @@ export declare class SecrecyCloudClient {
133
128
  }[];
134
129
  missingDataAccesses: {
135
130
  userId: string;
136
- dataId: string;
137
131
  nodeId: string;
132
+ dataId: string;
138
133
  }[];
139
134
  invalidRightsAccesses: {
140
135
  userId: string;
141
- current: {
142
- rights: "delete" | "write" | "read";
143
- } & {
144
- addAccess?: "delete" | "write" | "read" | null | undefined;
145
- sharingAddAccess?: "delete" | "write" | "read" | null | undefined;
146
- delAccess?: "delete" | "write" | "read" | null | undefined;
147
- sharingDelAccess?: "delete" | "write" | "read" | null | undefined;
148
- };
149
136
  nodeId: string;
150
137
  expect: {
151
- rights: "delete" | "write" | "read";
138
+ rights: "delete" | "read" | "write";
152
139
  } & {
153
- addAccess?: "delete" | "write" | "read" | null | undefined;
154
- sharingAddAccess?: "delete" | "write" | "read" | null | undefined;
155
- delAccess?: "delete" | "write" | "read" | null | undefined;
156
- sharingDelAccess?: "delete" | "write" | "read" | null | undefined;
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;
157
152
  };
158
153
  }[];
159
154
  };
160
- isMatching: false;
161
155
  }>;
162
156
  createPublicDataLink(input: RouterInputs['cloud']['createDataLink']): Promise<{
163
- name: string;
164
157
  id: string;
165
- createdByUserId: string | null;
166
- createdByAppId: string | null;
167
- createdByOrgId: string | null;
158
+ name: string;
168
159
  slug: string;
169
160
  expireAt: Date | null;
170
161
  dataId: string;
171
162
  }>;
172
163
  updatePublicDataLink(input: RouterInputs['cloud']['updateDataLink']): Promise<{
173
- name: string;
174
164
  id: string;
175
- createdByUserId: string | null;
176
- createdByAppId: string | null;
177
- createdByOrgId: string | null;
165
+ name: string;
178
166
  slug: string;
179
167
  expireAt: Date | null;
180
168
  dataId: string;
181
169
  }>;
182
170
  deletePublicDataLink(input: RouterInputs['cloud']['deleteDataLink']): Promise<{
183
- name: string;
184
171
  id: string;
185
- createdByUserId: string | null;
186
- createdByAppId: string | null;
187
- createdByOrgId: string | null;
172
+ name: string;
188
173
  slug: string;
189
174
  expireAt: Date | null;
190
175
  dataId: string;
@@ -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';
@@ -12,7 +12,7 @@ import { SecrecyUserClient } from './SecrecyUserClient.js';
12
12
  import { SecrecyPseudonymClient } from './SecrecyPseudonymClient.js';
13
13
  import { SecrecyOrganizationClient } from './SecrecyOrganizationClient.js';
14
14
  export type NewMail = Pick<RouterInputs['mail']['createDraft'], 'body' | 'subject' | 'senderFiles' | 'recipients' | 'replyToId'>;
15
- export type ProgressCallback = (progress: Progress) => Promise<void>;
15
+ export type ProgressCallback = (progress: SecretStreamProgress) => Promise<void>;
16
16
  export interface SecrecyClientOptions {
17
17
  uaSession: string;
18
18
  uaKeys: KeyPair;
@@ -7,7 +7,7 @@ export type LocalData = {
7
7
  storageType: DataStorageType;
8
8
  size: bigint;
9
9
  sizeEncrypted: bigint | null;
10
- data: Uint8Array;
10
+ data: Uint8Array<ArrayBuffer>;
11
11
  mime?: string;
12
12
  ext?: string;
13
13
  };
@@ -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>;