@secrecy/lib 1.68.0-feat-anonymous-upload.1 → 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,7 +142,7 @@ export class SecrecyCloudClient {
148
142
  signal,
149
143
  });
150
144
  if (uploadData.parts.length === 0) {
151
- if (uploadData.keyPair?.pub !== this.#keys.publicKey) {
145
+ if (uploadData.keyPair.pub !== this.#keys.publicKey) {
152
146
  throw new Error('The public key does not match with cached key!');
153
147
  }
154
148
  await uploadProgress?.({
@@ -168,11 +162,7 @@ export class SecrecyCloudClient {
168
162
  return localData;
169
163
  }
170
164
  const uploadDataPartEnd = async (md5, order) => {
171
- return this.#apiClient.cloud.uploadDataPartEnd.mutate({
172
- dataId: uploadData.id,
173
- md5,
174
- order,
175
- }, { signal });
165
+ return this.#apiClient.cloud.uploadDataPartEnd.mutate({ dataId: uploadData.id, md5, order }, { signal });
176
166
  };
177
167
  const chunkParts = new Array();
178
168
  for (const [index, chunk] of enumerate(chunks(encryptedData, Number(uploadData.partSize)))) {
@@ -185,7 +175,7 @@ export class SecrecyCloudClient {
185
175
  const progressParts = {};
186
176
  const onProgress = (part, progressEvent) => {
187
177
  progressParts[part] = progressEvent;
188
- 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);
189
179
  void uploadProgress?.({
190
180
  percent: current / encryptedData.byteLength,
191
181
  total: encryptedData.byteLength,
@@ -202,11 +192,21 @@ export class SecrecyCloudClient {
202
192
  formData.append(key, value);
203
193
  }
204
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
+ // })
205
202
  await axios.post(part.url, formData, {
206
203
  onUploadProgress: (progressEvent) => {
207
- onProgress(part.order, progressEvent);
204
+ onProgress(part.order, {
205
+ percent: progressEvent.progress ?? 0,
206
+ totalBytes: progressEvent.total ?? 0,
207
+ transferredBytes: progressEvent.loaded,
208
+ });
208
209
  },
209
- signal,
210
210
  });
211
211
  return uploadDataPartEnd(chunk.md5, chunk.order);
212
212
  };
@@ -234,11 +234,7 @@ export class SecrecyCloudClient {
234
234
  uploadProgress,
235
235
  signal,
236
236
  });
237
- return await this.saveInCloud({
238
- dataId: uploadedData.id,
239
- name,
240
- nodeId,
241
- });
237
+ return await this.saveInCloud({ dataId: uploadedData.id, name, nodeId });
242
238
  }
243
239
  async deletedNodes() {
244
240
  const deletedNodes = await this.#apiClient.cloud.nodesDeleted.query({});
@@ -249,9 +245,7 @@ export class SecrecyCloudClient {
249
245
  return await Promise.all(nodesShared.map(async (node) => await apiNodeToExternal(node, this.#keys)));
250
246
  }
251
247
  async nodesSharedWithMe(type = 'FOLDER') {
252
- const nodesSharedWithMe = await this.#apiClient.cloud.nodesSharedWithMe.query({
253
- type,
254
- });
248
+ const nodesSharedWithMe = await this.#apiClient.cloud.nodesSharedWithMe.query({ type });
255
249
  return await Promise.all(nodesSharedWithMe.map(async (node) => await apiNodeToExternal(node, this.#keys)));
256
250
  }
257
251
  async deleteNodeSharing({ nodeId, userId, }) {
@@ -285,9 +279,7 @@ export class SecrecyCloudClient {
285
279
  return isDuplicated;
286
280
  }
287
281
  async deleteNodeCloudTrash({ ids }) {
288
- const { isDeleted } = await this.#apiClient.cloud.deleteNodeCloudTrash.mutate({
289
- ids,
290
- });
282
+ const { isDeleted } = await this.#apiClient.cloud.deleteNodeCloudTrash.mutate({ ids });
291
283
  return isDeleted;
292
284
  }
293
285
  async createFolder({ name, parentFolderId, }) {
@@ -318,16 +310,11 @@ export class SecrecyCloudClient {
318
310
  return folder;
319
311
  }
320
312
  async node({ id, deleted, } = {}) {
321
- const node = await this.#apiClient.cloud.nodeFullById.query({
322
- id,
323
- deleted,
324
- });
313
+ const node = await this.#apiClient.cloud.nodeFullById.query({ id, deleted });
325
314
  return await apiNodeToExternalNodeFull(node, this.#keys);
326
315
  }
327
316
  async dataMetadata({ id }) {
328
- const data = await this.#apiClient.cloud.dataById.query({
329
- id,
330
- });
317
+ const data = await this.#apiClient.cloud.dataById.query({ id });
331
318
  return apiDataToExternal(data, this.#keys);
332
319
  }
333
320
  async shareNode(input, progress) {
@@ -339,11 +326,7 @@ export class SecrecyCloudClient {
339
326
  const publicKeysMap = await this.#client.app.userPublicKey(neededUserKey);
340
327
  const maxNodesBatchSize = 1000;
341
328
  const totalNodesToShare = Object.values(nodesMap).reduce((size, ids) => size + ids.length, 0);
342
- progress?.({
343
- total: totalNodesToShare,
344
- current: 0,
345
- percent: 0,
346
- });
329
+ progress?.({ total: totalNodesToShare, current: 0, percent: 0 });
347
330
  const chunks = totalNodesToShare > maxNodesBatchSize
348
331
  ? chunkByTotalItems(nodesMap, maxNodesBatchSize)
349
332
  : [nodesMap];
@@ -464,13 +447,7 @@ export class SecrecyCloudClient {
464
447
  for (const [userId, nodes] of Object.entries(nodesToUpdateRights)) {
465
448
  finishInput.push(...nodes.map((node) => ({
466
449
  userId,
467
- nodes: [
468
- {
469
- id: node.nodeId,
470
- data: [],
471
- ...node.permissions,
472
- },
473
- ],
450
+ nodes: [{ id: node.nodeId, data: [], ...node.permissions }],
474
451
  })));
475
452
  }
476
453
  const subState = await this.#apiClient.cloud.shareNodeFinish.mutate(finishInput);
@@ -508,10 +485,7 @@ export class SecrecyCloudClient {
508
485
  const errorDetailsLength = details.invalidRightsAccesses.length +
509
486
  details.missingDataAccesses.length +
510
487
  details.missingNodeAccesses.length;
511
- return {
512
- isFinished: errorDetailsLength === 0,
513
- details: details,
514
- };
488
+ return { isFinished: errorDetailsLength === 0, details: details };
515
489
  }
516
490
  async updateNode({ nodeId, name, isFavorite, deletedAt, }) {
517
491
  let node = nodesCache.get(nodeId);
@@ -594,9 +568,7 @@ export class SecrecyCloudClient {
594
568
  }));
595
569
  }
596
570
  async deleteNodes({ nodeIds, }) {
597
- return this.#apiClient.cloud.deleteNodes.mutate({
598
- ids: nodeIds,
599
- });
571
+ return this.#apiClient.cloud.deleteNodes.mutate({ ids: nodeIds });
600
572
  }
601
573
  async deleteData({ dataId, nodeId, }) {
602
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>;