@protontech/drive-sdk 0.6.2 → 0.7.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.
Files changed (158) hide show
  1. package/dist/interface/index.d.ts +1 -0
  2. package/dist/interface/index.js.map +1 -1
  3. package/dist/interface/nodes.d.ts +14 -10
  4. package/dist/interface/nodes.js +5 -8
  5. package/dist/interface/nodes.js.map +1 -1
  6. package/dist/interface/photos.d.ts +62 -0
  7. package/dist/interface/photos.js +3 -0
  8. package/dist/interface/photos.js.map +1 -0
  9. package/dist/internal/apiService/apiService.d.ts +2 -2
  10. package/dist/internal/apiService/apiService.js.map +1 -1
  11. package/dist/internal/apiService/driveTypes.d.ts +1294 -517
  12. package/dist/internal/apiService/errors.js +4 -3
  13. package/dist/internal/apiService/errors.js.map +1 -1
  14. package/dist/internal/download/cryptoService.js +8 -6
  15. package/dist/internal/download/cryptoService.js.map +1 -1
  16. package/dist/internal/download/fileDownloader.d.ts +2 -1
  17. package/dist/internal/download/fileDownloader.js +6 -3
  18. package/dist/internal/download/fileDownloader.js.map +1 -1
  19. package/dist/internal/download/index.d.ts +1 -1
  20. package/dist/internal/download/index.js +3 -3
  21. package/dist/internal/download/index.js.map +1 -1
  22. package/dist/internal/errors.d.ts +1 -0
  23. package/dist/internal/errors.js +4 -0
  24. package/dist/internal/errors.js.map +1 -1
  25. package/dist/internal/nodes/apiService.d.ts +68 -16
  26. package/dist/internal/nodes/apiService.js +138 -85
  27. package/dist/internal/nodes/apiService.js.map +1 -1
  28. package/dist/internal/nodes/apiService.test.js +7 -5
  29. package/dist/internal/nodes/apiService.test.js.map +1 -1
  30. package/dist/internal/nodes/cache.d.ts +16 -8
  31. package/dist/internal/nodes/cache.js +19 -5
  32. package/dist/internal/nodes/cache.js.map +1 -1
  33. package/dist/internal/nodes/cache.test.js +1 -0
  34. package/dist/internal/nodes/cache.test.js.map +1 -1
  35. package/dist/internal/nodes/cryptoReporter.d.ts +3 -3
  36. package/dist/internal/nodes/cryptoReporter.js.map +1 -1
  37. package/dist/internal/nodes/cryptoService.d.ts +13 -22
  38. package/dist/internal/nodes/cryptoService.js +47 -16
  39. package/dist/internal/nodes/cryptoService.js.map +1 -1
  40. package/dist/internal/nodes/cryptoService.test.js +262 -17
  41. package/dist/internal/nodes/cryptoService.test.js.map +1 -1
  42. package/dist/internal/nodes/events.d.ts +2 -2
  43. package/dist/internal/nodes/events.js.map +1 -1
  44. package/dist/internal/nodes/index.test.js +1 -0
  45. package/dist/internal/nodes/index.test.js.map +1 -1
  46. package/dist/internal/nodes/interface.d.ts +14 -3
  47. package/dist/internal/nodes/nodesAccess.d.ts +36 -20
  48. package/dist/internal/nodes/nodesAccess.js +54 -29
  49. package/dist/internal/nodes/nodesAccess.js.map +1 -1
  50. package/dist/internal/nodes/nodesManagement.d.ts +34 -14
  51. package/dist/internal/nodes/nodesManagement.js +44 -31
  52. package/dist/internal/nodes/nodesManagement.js.map +1 -1
  53. package/dist/internal/nodes/nodesManagement.test.js +60 -14
  54. package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
  55. package/dist/internal/nodes/nodesRevisions.d.ts +2 -2
  56. package/dist/internal/nodes/nodesRevisions.js.map +1 -1
  57. package/dist/internal/photos/albums.d.ts +2 -2
  58. package/dist/internal/photos/albums.js.map +1 -1
  59. package/dist/internal/photos/index.d.ts +19 -3
  60. package/dist/internal/photos/index.js +38 -8
  61. package/dist/internal/photos/index.js.map +1 -1
  62. package/dist/internal/photos/interface.d.ts +18 -9
  63. package/dist/internal/photos/nodes.d.ts +57 -0
  64. package/dist/internal/photos/nodes.js +165 -0
  65. package/dist/internal/photos/nodes.js.map +1 -0
  66. package/dist/internal/photos/timeline.d.ts +2 -2
  67. package/dist/internal/photos/timeline.js.map +1 -1
  68. package/dist/internal/photos/timeline.test.js.map +1 -1
  69. package/dist/internal/photos/upload.d.ts +2 -2
  70. package/dist/internal/photos/upload.js.map +1 -1
  71. package/dist/internal/sharingPublic/index.d.ts +6 -6
  72. package/dist/internal/sharingPublic/index.js +8 -7
  73. package/dist/internal/sharingPublic/index.js.map +1 -1
  74. package/dist/internal/sharingPublic/nodes.d.ts +16 -3
  75. package/dist/internal/sharingPublic/nodes.js +34 -2
  76. package/dist/internal/sharingPublic/nodes.js.map +1 -1
  77. package/dist/internal/sharingPublic/unauthApiService.d.ts +17 -0
  78. package/dist/internal/sharingPublic/unauthApiService.js +31 -0
  79. package/dist/internal/sharingPublic/unauthApiService.js.map +1 -0
  80. package/dist/internal/sharingPublic/unauthApiService.test.d.ts +1 -0
  81. package/dist/internal/sharingPublic/unauthApiService.test.js +27 -0
  82. package/dist/internal/sharingPublic/unauthApiService.test.js.map +1 -0
  83. package/dist/internal/upload/apiService.d.ts +4 -3
  84. package/dist/internal/upload/apiService.js.map +1 -1
  85. package/dist/internal/upload/cryptoService.d.ts +8 -3
  86. package/dist/internal/upload/cryptoService.js +45 -9
  87. package/dist/internal/upload/cryptoService.js.map +1 -1
  88. package/dist/internal/upload/fileUploader.test.js +1 -1
  89. package/dist/internal/upload/fileUploader.test.js.map +1 -1
  90. package/dist/internal/upload/interface.d.ts +25 -13
  91. package/dist/internal/upload/manager.js +7 -4
  92. package/dist/internal/upload/manager.js.map +1 -1
  93. package/dist/internal/upload/manager.test.js +5 -4
  94. package/dist/internal/upload/manager.test.js.map +1 -1
  95. package/dist/internal/upload/streamUploader.js +9 -4
  96. package/dist/internal/upload/streamUploader.js.map +1 -1
  97. package/dist/internal/upload/streamUploader.test.js +8 -5
  98. package/dist/internal/upload/streamUploader.test.js.map +1 -1
  99. package/dist/protonDriveClient.d.ts +11 -2
  100. package/dist/protonDriveClient.js +20 -4
  101. package/dist/protonDriveClient.js.map +1 -1
  102. package/dist/protonDrivePhotosClient.d.ts +8 -8
  103. package/dist/protonDrivePhotosClient.js +8 -9
  104. package/dist/protonDrivePhotosClient.js.map +1 -1
  105. package/dist/protonDrivePublicLinkClient.d.ts +9 -2
  106. package/dist/protonDrivePublicLinkClient.js +16 -5
  107. package/dist/protonDrivePublicLinkClient.js.map +1 -1
  108. package/dist/transformers.d.ts +7 -2
  109. package/dist/transformers.js +37 -0
  110. package/dist/transformers.js.map +1 -1
  111. package/package.json +1 -1
  112. package/src/interface/index.ts +1 -0
  113. package/src/interface/nodes.ts +14 -11
  114. package/src/interface/photos.ts +67 -0
  115. package/src/internal/apiService/apiService.ts +2 -2
  116. package/src/internal/apiService/driveTypes.ts +1294 -517
  117. package/src/internal/apiService/errors.ts +5 -4
  118. package/src/internal/download/cryptoService.ts +13 -6
  119. package/src/internal/download/fileDownloader.ts +4 -2
  120. package/src/internal/download/index.ts +3 -0
  121. package/src/internal/errors.ts +4 -0
  122. package/src/internal/nodes/apiService.test.ts +7 -5
  123. package/src/internal/nodes/apiService.ts +210 -124
  124. package/src/internal/nodes/cache.test.ts +1 -0
  125. package/src/internal/nodes/cache.ts +32 -13
  126. package/src/internal/nodes/cryptoReporter.ts +3 -3
  127. package/src/internal/nodes/cryptoService.test.ts +380 -18
  128. package/src/internal/nodes/cryptoService.ts +77 -36
  129. package/src/internal/nodes/events.ts +2 -2
  130. package/src/internal/nodes/index.test.ts +1 -0
  131. package/src/internal/nodes/interface.ts +17 -2
  132. package/src/internal/nodes/nodesAccess.ts +99 -54
  133. package/src/internal/nodes/nodesManagement.test.ts +69 -14
  134. package/src/internal/nodes/nodesManagement.ts +94 -48
  135. package/src/internal/nodes/nodesRevisions.ts +3 -3
  136. package/src/internal/photos/albums.ts +2 -2
  137. package/src/internal/photos/index.ts +45 -3
  138. package/src/internal/photos/interface.ts +21 -9
  139. package/src/internal/photos/nodes.ts +233 -0
  140. package/src/internal/photos/timeline.test.ts +2 -2
  141. package/src/internal/photos/timeline.ts +2 -2
  142. package/src/internal/photos/upload.ts +3 -3
  143. package/src/internal/sharingPublic/index.ts +7 -3
  144. package/src/internal/sharingPublic/nodes.ts +43 -2
  145. package/src/internal/sharingPublic/unauthApiService.test.ts +29 -0
  146. package/src/internal/sharingPublic/unauthApiService.ts +32 -0
  147. package/src/internal/upload/apiService.ts +4 -3
  148. package/src/internal/upload/cryptoService.ts +73 -12
  149. package/src/internal/upload/fileUploader.test.ts +1 -1
  150. package/src/internal/upload/interface.ts +24 -13
  151. package/src/internal/upload/manager.test.ts +5 -4
  152. package/src/internal/upload/manager.ts +7 -4
  153. package/src/internal/upload/streamUploader.test.ts +8 -5
  154. package/src/internal/upload/streamUploader.ts +10 -4
  155. package/src/protonDriveClient.ts +27 -5
  156. package/src/protonDrivePhotosClient.ts +23 -23
  157. package/src/protonDrivePublicLinkClient.ts +19 -3
  158. package/src/transformers.ts +49 -2
@@ -30,7 +30,7 @@ export function apiErrorFactory({
30
30
  Code?: number;
31
31
  Error?: string;
32
32
  Details?: object;
33
- exception?: string;
33
+ Exception?: string;
34
34
  message?: string;
35
35
  file?: string;
36
36
  line?: number;
@@ -43,9 +43,10 @@ export function apiErrorFactory({
43
43
  typedResult.Details,
44
44
  ];
45
45
 
46
- const debug = typedResult.exception
46
+ const debug = typedResult.Exception
47
47
  ? {
48
- exception: typedResult.exception,
48
+ details: typedResult.Details,
49
+ exception: typedResult.Exception,
49
50
  message: typedResult.message,
50
51
  file: typedResult.file,
51
52
  line: typedResult.line,
@@ -82,7 +83,7 @@ export function apiErrorFactory({
82
83
  case ErrorCode.INSUFFICIENT_BOOKMARKS_QUOTA:
83
84
  return new ValidationError(message, code, details);
84
85
  default:
85
- return new APICodeError(message, code, debug);
86
+ return new APICodeError(message, code, debug || details);
86
87
  }
87
88
  }
88
89
 
@@ -27,7 +27,7 @@ export class DownloadCryptoService {
27
27
  nodeKey: { key: PrivateKey; contentKeyPacketSessionKey: SessionKey },
28
28
  revision: Revision,
29
29
  ): Promise<RevisionKeys> {
30
- const verificationKeys = await this.getRevisionVerificationKeys(revision);
30
+ const verificationKeys = await this.getRevisionVerificationKeys(revision, nodeKey.key);
31
31
  return {
32
32
  ...nodeKey,
33
33
  verificationKeys,
@@ -90,23 +90,30 @@ export class DownloadCryptoService {
90
90
  allBlockHashes: Uint8Array[],
91
91
  armoredManifestSignature?: string,
92
92
  ): Promise<void> {
93
- const verificationKeys = (await this.getRevisionVerificationKeys(revision)) || nodeKey;
93
+ const verificationKeys = await this.getRevisionVerificationKeys(revision, nodeKey);
94
94
  const hash = mergeUint8Arrays(allBlockHashes);
95
95
 
96
96
  if (!armoredManifestSignature) {
97
97
  throw new IntegrityError(c('Error').t`Missing integrity signature`);
98
98
  }
99
99
 
100
- const { verified } = await this.driveCrypto.verifyManifest(hash, armoredManifestSignature, verificationKeys);
100
+ const { verified, verificationErrors } = await this.driveCrypto.verifyManifest(
101
+ hash,
102
+ armoredManifestSignature,
103
+ verificationKeys,
104
+ );
105
+
101
106
  if (verified !== VERIFICATION_STATUS.SIGNED_AND_VALID) {
102
- throw new IntegrityError(c('Error').t`Data integrity check failed`);
107
+ throw new IntegrityError(c('Error').t`Data integrity check failed`, {
108
+ verificationErrors,
109
+ });
103
110
  }
104
111
  }
105
112
 
106
- private async getRevisionVerificationKeys(revision: Revision): Promise<PublicKey[] | undefined> {
113
+ private async getRevisionVerificationKeys(revision: Revision, nodeKey: PrivateKey): Promise<PublicKey[]> {
107
114
  const signatureEmail = revision.contentAuthor.ok
108
115
  ? revision.contentAuthor.value
109
116
  : revision.contentAuthor.error.claimedAuthor;
110
- return signatureEmail ? await this.account.getPublicKeys(signatureEmail) : undefined;
117
+ return signatureEmail ? await this.account.getPublicKeys(signatureEmail) : [nodeKey];
111
118
  }
112
119
  }
@@ -42,6 +42,7 @@ export class FileDownloader {
42
42
  private revision: DecryptedRevision,
43
43
  private signal?: AbortSignal,
44
44
  private onFinish?: () => void,
45
+ private ignoreManifestVerification = false,
45
46
  ) {
46
47
  this.telemetry = telemetry;
47
48
  this.logger = telemetry.getLoggerForRevision(revision.uid);
@@ -51,6 +52,7 @@ export class FileDownloader {
51
52
  this.revision = revision;
52
53
  this.signal = signal;
53
54
  this.onFinish = onFinish;
55
+ this.ignoreManifestVerification = ignoreManifestVerification;
54
56
  this.controller = new DownloadController(this.signal);
55
57
  }
56
58
 
@@ -219,7 +221,7 @@ export class FileDownloader {
219
221
  throw new Error(`Some blocks were not downloaded`);
220
222
  }
221
223
 
222
- if (ignoreIntegrityErrors) {
224
+ if (ignoreIntegrityErrors || this.ignoreManifestVerification) {
223
225
  this.logger.warn('Skipping manifest check');
224
226
  } else {
225
227
  this.logger.debug(`Verifying manifest`);
@@ -237,7 +239,7 @@ export class FileDownloader {
237
239
  } catch (error: unknown) {
238
240
  this.logger.error(`Download failed`, error);
239
241
  void this.telemetry.downloadFailed(this.revision.uid, error, fileProgress, this.getClaimedSizeInBytes());
240
- await writer.abort();
242
+ await writer.abort?.();
241
243
  throw error;
242
244
  } finally {
243
245
  this.logger.debug(`Download cleanup`);
@@ -21,6 +21,7 @@ export function initDownloadModule(
21
21
  sharesService: SharesService,
22
22
  nodesService: NodesService,
23
23
  revisionsService: RevisionsService,
24
+ ignoreManifestVerification = false,
24
25
  ) {
25
26
  const queue = new DownloadQueue();
26
27
  const api = new DownloadAPIService(apiService);
@@ -63,6 +64,7 @@ export function initDownloadModule(
63
64
  node.activeRevision.value,
64
65
  signal,
65
66
  onFinish,
67
+ ignoreManifestVerification,
66
68
  );
67
69
  }
68
70
 
@@ -102,6 +104,7 @@ export function initDownloadModule(
102
104
  revision,
103
105
  signal,
104
106
  onFinish,
107
+ ignoreManifestVerification,
105
108
  );
106
109
  }
107
110
 
@@ -3,6 +3,10 @@ import { c } from 'ttag';
3
3
  import { VERIFICATION_STATUS } from '../crypto';
4
4
  import { AbortError, ConnectionError, RateLimitedError, ValidationError } from '../errors';
5
5
 
6
+ export function createErrorFromUnknown(error: unknown): Error {
7
+ return error instanceof Error ? error : new Error(getErrorMessage(error), { cause: error });
8
+ }
9
+
6
10
  export function getErrorMessage(error: unknown): string {
7
11
  return error instanceof Error ? error.message : c('Error').t`Unknown error`;
8
12
  }
@@ -65,6 +65,7 @@ function generateAPINode() {
65
65
  ParentLinkID: 'parentLinkId',
66
66
  NameHash: 'nameHash',
67
67
  CreateTime: 123456789,
68
+ ModifyTime: 1234567890,
68
69
  TrashTime: 0,
69
70
 
70
71
  Name: 'encName',
@@ -140,6 +141,7 @@ function generateNode() {
140
141
  uid: 'volumeId~linkId',
141
142
  parentUid: 'volumeId~parentLinkId',
142
143
  creationTime: new Date(123456789000),
144
+ modificationTime: new Date(1234567890000),
143
145
  trashTime: undefined,
144
146
 
145
147
  shareId: undefined,
@@ -577,8 +579,8 @@ describe('nodeAPIService', () => {
577
579
  });
578
580
  });
579
581
 
580
- describe('deleteNodes', () => {
581
- it('should delete nodes', async () => {
582
+ describe('deleteTrashedNodes', () => {
583
+ it('should delete trashed nodes', async () => {
582
584
  // @ts-expect-error Mocking for testing purposes
583
585
  apiMock.post = jest.fn(async () =>
584
586
  Promise.resolve({
@@ -600,14 +602,14 @@ describe('nodeAPIService', () => {
600
602
  }),
601
603
  );
602
604
 
603
- const result = await Array.fromAsync(api.deleteNodes(['volumeId~nodeId1', 'volumeId~nodeId2']));
605
+ const result = await Array.fromAsync(api.deleteTrashedNodes(['volumeId~nodeId1', 'volumeId~nodeId2']));
604
606
  expect(result).toEqual([
605
607
  { uid: 'volumeId~nodeId1', ok: true },
606
608
  { uid: 'volumeId~nodeId2', ok: false, error: 'INSUFFICIENT_SCOPE' },
607
609
  ]);
608
610
  });
609
611
 
610
- it('should delete nodes from multiple volumes', async () => {
612
+ it('should delete trashed nodes from multiple volumes', async () => {
611
613
  // @ts-expect-error Mocking for testing purposes
612
614
  apiMock.post = jest.fn(async (_, { LinkIDs }) =>
613
615
  Promise.resolve({
@@ -620,7 +622,7 @@ describe('nodeAPIService', () => {
620
622
  }),
621
623
  );
622
624
 
623
- const result = await Array.fromAsync(api.deleteNodes(['volumeId1~nodeId1', 'volumeId2~nodeId2']));
625
+ const result = await Array.fromAsync(api.deleteTrashedNodes(['volumeId1~nodeId1', 'volumeId2~nodeId2']));
624
626
  expect(result).toEqual([
625
627
  { uid: 'volumeId1~nodeId1', ok: true },
626
628
  { uid: 'volumeId2~nodeId2', ok: true },