@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.
- package/dist/interface/index.d.ts +1 -0
- package/dist/interface/index.js.map +1 -1
- package/dist/interface/nodes.d.ts +14 -10
- package/dist/interface/nodes.js +5 -8
- package/dist/interface/nodes.js.map +1 -1
- package/dist/interface/photos.d.ts +62 -0
- package/dist/interface/photos.js +3 -0
- package/dist/interface/photos.js.map +1 -0
- package/dist/internal/apiService/apiService.d.ts +2 -2
- package/dist/internal/apiService/apiService.js.map +1 -1
- package/dist/internal/apiService/driveTypes.d.ts +1294 -517
- package/dist/internal/apiService/errors.js +4 -3
- package/dist/internal/apiService/errors.js.map +1 -1
- package/dist/internal/download/cryptoService.js +8 -6
- package/dist/internal/download/cryptoService.js.map +1 -1
- package/dist/internal/download/fileDownloader.d.ts +2 -1
- package/dist/internal/download/fileDownloader.js +6 -3
- package/dist/internal/download/fileDownloader.js.map +1 -1
- package/dist/internal/download/index.d.ts +1 -1
- package/dist/internal/download/index.js +3 -3
- package/dist/internal/download/index.js.map +1 -1
- package/dist/internal/errors.d.ts +1 -0
- package/dist/internal/errors.js +4 -0
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/nodes/apiService.d.ts +68 -16
- package/dist/internal/nodes/apiService.js +138 -85
- package/dist/internal/nodes/apiService.js.map +1 -1
- package/dist/internal/nodes/apiService.test.js +7 -5
- package/dist/internal/nodes/apiService.test.js.map +1 -1
- package/dist/internal/nodes/cache.d.ts +16 -8
- package/dist/internal/nodes/cache.js +19 -5
- package/dist/internal/nodes/cache.js.map +1 -1
- package/dist/internal/nodes/cache.test.js +1 -0
- package/dist/internal/nodes/cache.test.js.map +1 -1
- package/dist/internal/nodes/cryptoReporter.d.ts +3 -3
- package/dist/internal/nodes/cryptoReporter.js.map +1 -1
- package/dist/internal/nodes/cryptoService.d.ts +13 -22
- package/dist/internal/nodes/cryptoService.js +47 -16
- package/dist/internal/nodes/cryptoService.js.map +1 -1
- package/dist/internal/nodes/cryptoService.test.js +262 -17
- package/dist/internal/nodes/cryptoService.test.js.map +1 -1
- package/dist/internal/nodes/events.d.ts +2 -2
- package/dist/internal/nodes/events.js.map +1 -1
- package/dist/internal/nodes/index.test.js +1 -0
- package/dist/internal/nodes/index.test.js.map +1 -1
- package/dist/internal/nodes/interface.d.ts +14 -3
- package/dist/internal/nodes/nodesAccess.d.ts +36 -20
- package/dist/internal/nodes/nodesAccess.js +54 -29
- package/dist/internal/nodes/nodesAccess.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.d.ts +34 -14
- package/dist/internal/nodes/nodesManagement.js +44 -31
- package/dist/internal/nodes/nodesManagement.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.test.js +60 -14
- package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
- package/dist/internal/nodes/nodesRevisions.d.ts +2 -2
- package/dist/internal/nodes/nodesRevisions.js.map +1 -1
- package/dist/internal/photos/albums.d.ts +2 -2
- package/dist/internal/photos/albums.js.map +1 -1
- package/dist/internal/photos/index.d.ts +19 -3
- package/dist/internal/photos/index.js +38 -8
- package/dist/internal/photos/index.js.map +1 -1
- package/dist/internal/photos/interface.d.ts +18 -9
- package/dist/internal/photos/nodes.d.ts +57 -0
- package/dist/internal/photos/nodes.js +165 -0
- package/dist/internal/photos/nodes.js.map +1 -0
- package/dist/internal/photos/timeline.d.ts +2 -2
- package/dist/internal/photos/timeline.js.map +1 -1
- package/dist/internal/photos/timeline.test.js.map +1 -1
- package/dist/internal/photos/upload.d.ts +2 -2
- package/dist/internal/photos/upload.js.map +1 -1
- package/dist/internal/sharingPublic/index.d.ts +6 -6
- package/dist/internal/sharingPublic/index.js +8 -7
- package/dist/internal/sharingPublic/index.js.map +1 -1
- package/dist/internal/sharingPublic/nodes.d.ts +16 -3
- package/dist/internal/sharingPublic/nodes.js +34 -2
- package/dist/internal/sharingPublic/nodes.js.map +1 -1
- package/dist/internal/sharingPublic/unauthApiService.d.ts +17 -0
- package/dist/internal/sharingPublic/unauthApiService.js +31 -0
- package/dist/internal/sharingPublic/unauthApiService.js.map +1 -0
- package/dist/internal/sharingPublic/unauthApiService.test.d.ts +1 -0
- package/dist/internal/sharingPublic/unauthApiService.test.js +27 -0
- package/dist/internal/sharingPublic/unauthApiService.test.js.map +1 -0
- package/dist/internal/upload/apiService.d.ts +4 -3
- package/dist/internal/upload/apiService.js.map +1 -1
- package/dist/internal/upload/cryptoService.d.ts +8 -3
- package/dist/internal/upload/cryptoService.js +45 -9
- package/dist/internal/upload/cryptoService.js.map +1 -1
- package/dist/internal/upload/fileUploader.test.js +1 -1
- package/dist/internal/upload/fileUploader.test.js.map +1 -1
- package/dist/internal/upload/interface.d.ts +25 -13
- package/dist/internal/upload/manager.js +7 -4
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +5 -4
- package/dist/internal/upload/manager.test.js.map +1 -1
- package/dist/internal/upload/streamUploader.js +9 -4
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.test.js +8 -5
- package/dist/internal/upload/streamUploader.test.js.map +1 -1
- package/dist/protonDriveClient.d.ts +11 -2
- package/dist/protonDriveClient.js +20 -4
- package/dist/protonDriveClient.js.map +1 -1
- package/dist/protonDrivePhotosClient.d.ts +8 -8
- package/dist/protonDrivePhotosClient.js +8 -9
- package/dist/protonDrivePhotosClient.js.map +1 -1
- package/dist/protonDrivePublicLinkClient.d.ts +9 -2
- package/dist/protonDrivePublicLinkClient.js +16 -5
- package/dist/protonDrivePublicLinkClient.js.map +1 -1
- package/dist/transformers.d.ts +7 -2
- package/dist/transformers.js +37 -0
- package/dist/transformers.js.map +1 -1
- package/package.json +1 -1
- package/src/interface/index.ts +1 -0
- package/src/interface/nodes.ts +14 -11
- package/src/interface/photos.ts +67 -0
- package/src/internal/apiService/apiService.ts +2 -2
- package/src/internal/apiService/driveTypes.ts +1294 -517
- package/src/internal/apiService/errors.ts +5 -4
- package/src/internal/download/cryptoService.ts +13 -6
- package/src/internal/download/fileDownloader.ts +4 -2
- package/src/internal/download/index.ts +3 -0
- package/src/internal/errors.ts +4 -0
- package/src/internal/nodes/apiService.test.ts +7 -5
- package/src/internal/nodes/apiService.ts +210 -124
- package/src/internal/nodes/cache.test.ts +1 -0
- package/src/internal/nodes/cache.ts +32 -13
- package/src/internal/nodes/cryptoReporter.ts +3 -3
- package/src/internal/nodes/cryptoService.test.ts +380 -18
- package/src/internal/nodes/cryptoService.ts +77 -36
- package/src/internal/nodes/events.ts +2 -2
- package/src/internal/nodes/index.test.ts +1 -0
- package/src/internal/nodes/interface.ts +17 -2
- package/src/internal/nodes/nodesAccess.ts +99 -54
- package/src/internal/nodes/nodesManagement.test.ts +69 -14
- package/src/internal/nodes/nodesManagement.ts +94 -48
- package/src/internal/nodes/nodesRevisions.ts +3 -3
- package/src/internal/photos/albums.ts +2 -2
- package/src/internal/photos/index.ts +45 -3
- package/src/internal/photos/interface.ts +21 -9
- package/src/internal/photos/nodes.ts +233 -0
- package/src/internal/photos/timeline.test.ts +2 -2
- package/src/internal/photos/timeline.ts +2 -2
- package/src/internal/photos/upload.ts +3 -3
- package/src/internal/sharingPublic/index.ts +7 -3
- package/src/internal/sharingPublic/nodes.ts +43 -2
- package/src/internal/sharingPublic/unauthApiService.test.ts +29 -0
- package/src/internal/sharingPublic/unauthApiService.ts +32 -0
- package/src/internal/upload/apiService.ts +4 -3
- package/src/internal/upload/cryptoService.ts +73 -12
- package/src/internal/upload/fileUploader.test.ts +1 -1
- package/src/internal/upload/interface.ts +24 -13
- package/src/internal/upload/manager.test.ts +5 -4
- package/src/internal/upload/manager.ts +7 -4
- package/src/internal/upload/streamUploader.test.ts +8 -5
- package/src/internal/upload/streamUploader.ts +10 -4
- package/src/protonDriveClient.ts +27 -5
- package/src/protonDrivePhotosClient.ts +23 -23
- package/src/protonDrivePublicLinkClient.ts +19 -3
- 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
|
-
|
|
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.
|
|
46
|
+
const debug = typedResult.Exception
|
|
47
47
|
? {
|
|
48
|
-
|
|
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 =
|
|
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(
|
|
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[]
|
|
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) :
|
|
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
|
|
package/src/internal/errors.ts
CHANGED
|
@@ -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('
|
|
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.
|
|
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.
|
|
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 },
|