@protontech/drive-sdk 0.5.0 → 0.5.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/diagnostic/{sdkDiagnosticFull.d.ts → diagnostic.d.ts} +5 -4
- package/dist/diagnostic/{sdkDiagnosticFull.js → diagnostic.js} +13 -10
- package/dist/diagnostic/diagnostic.js.map +1 -0
- package/dist/diagnostic/index.js +2 -4
- package/dist/diagnostic/index.js.map +1 -1
- package/dist/diagnostic/interface.d.ts +22 -1
- package/dist/diagnostic/sdkDiagnostic.d.ts +3 -2
- package/dist/diagnostic/sdkDiagnostic.js +79 -7
- package/dist/diagnostic/sdkDiagnostic.js.map +1 -1
- package/dist/interface/index.d.ts +1 -1
- package/dist/interface/index.js.map +1 -1
- package/dist/interface/nodes.d.ts +9 -0
- package/dist/interface/telemetry.d.ts +4 -1
- package/dist/interface/telemetry.js.map +1 -1
- package/dist/internal/apiService/driveTypes.d.ts +2571 -2356
- package/dist/internal/download/controller.d.ts +2 -0
- package/dist/internal/download/controller.js +15 -1
- package/dist/internal/download/controller.js.map +1 -1
- package/dist/internal/download/fileDownloader.js +6 -1
- package/dist/internal/download/fileDownloader.js.map +1 -1
- package/dist/internal/nodes/apiService.js +27 -12
- package/dist/internal/nodes/apiService.js.map +1 -1
- package/dist/internal/nodes/apiService.test.js +60 -2
- package/dist/internal/nodes/apiService.test.js.map +1 -1
- package/dist/internal/nodes/debouncer.d.ts +3 -2
- package/dist/internal/nodes/debouncer.js +16 -4
- package/dist/internal/nodes/debouncer.js.map +1 -1
- package/dist/internal/nodes/debouncer.test.js +20 -12
- package/dist/internal/nodes/debouncer.test.js.map +1 -1
- package/dist/internal/nodes/extendedAttributes.js +2 -2
- package/dist/internal/nodes/extendedAttributes.js.map +1 -1
- package/dist/internal/nodes/index.js +1 -1
- package/dist/internal/nodes/index.js.map +1 -1
- package/dist/internal/nodes/nodesAccess.d.ts +5 -4
- package/dist/internal/nodes/nodesAccess.js +6 -5
- package/dist/internal/nodes/nodesAccess.js.map +1 -1
- package/dist/internal/nodes/nodesAccess.test.js +17 -5
- package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.d.ts +2 -2
- package/dist/internal/nodes/nodesManagement.js +5 -3
- package/dist/internal/nodes/nodesManagement.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.test.js +3 -1
- package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
- package/dist/internal/photos/apiService.js +9 -20
- package/dist/internal/photos/apiService.js.map +1 -1
- package/dist/internal/photos/upload.js +7 -1
- package/dist/internal/photos/upload.js.map +1 -1
- package/dist/internal/sharing/apiService.d.ts +1 -1
- package/dist/internal/sharing/apiService.js +2 -2
- package/dist/internal/sharing/apiService.js.map +1 -1
- package/dist/internal/sharing/sharingManagement.d.ts +4 -1
- package/dist/internal/sharing/sharingManagement.js +7 -4
- package/dist/internal/sharing/sharingManagement.js.map +1 -1
- package/dist/internal/sharingPublic/apiService.d.ts +8 -10
- package/dist/internal/sharingPublic/apiService.js +9 -63
- package/dist/internal/sharingPublic/apiService.js.map +1 -1
- package/dist/internal/sharingPublic/index.d.ts +3 -3
- package/dist/internal/sharingPublic/index.js +5 -11
- package/dist/internal/sharingPublic/index.js.map +1 -1
- package/dist/internal/sharingPublic/nodes.d.ts +13 -8
- package/dist/internal/sharingPublic/nodes.js +20 -2
- package/dist/internal/sharingPublic/nodes.js.map +1 -1
- package/dist/internal/sharingPublic/session/apiService.d.ts +7 -5
- package/dist/internal/sharingPublic/session/apiService.js +25 -4
- package/dist/internal/sharingPublic/session/apiService.js.map +1 -1
- package/dist/internal/sharingPublic/session/interface.d.ts +17 -0
- package/dist/internal/sharingPublic/session/manager.d.ts +12 -4
- package/dist/internal/sharingPublic/session/manager.js +14 -4
- package/dist/internal/sharingPublic/session/manager.js.map +1 -1
- package/dist/internal/sharingPublic/session/session.d.ts +5 -2
- package/dist/internal/sharingPublic/session/session.js +7 -3
- package/dist/internal/sharingPublic/session/session.js.map +1 -1
- package/dist/internal/sharingPublic/shares.d.ts +3 -10
- package/dist/internal/sharingPublic/shares.js +10 -33
- package/dist/internal/sharingPublic/shares.js.map +1 -1
- package/dist/internal/upload/controller.d.ts +3 -1
- package/dist/internal/upload/controller.js +16 -2
- package/dist/internal/upload/controller.js.map +1 -1
- package/dist/internal/upload/fileUploader.js +2 -2
- package/dist/internal/upload/fileUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.d.ts +4 -3
- package/dist/internal/upload/streamUploader.js +61 -18
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.test.js +38 -12
- package/dist/internal/upload/streamUploader.test.js.map +1 -1
- package/dist/protonDriveClient.d.ts +8 -3
- package/dist/protonDriveClient.js +7 -6
- package/dist/protonDriveClient.js.map +1 -1
- package/dist/protonDrivePublicLinkClient.d.ts +4 -3
- package/dist/protonDrivePublicLinkClient.js +2 -2
- package/dist/protonDrivePublicLinkClient.js.map +1 -1
- package/dist/tests/telemetry.d.ts +4 -2
- package/dist/tests/telemetry.js +3 -1
- package/dist/tests/telemetry.js.map +1 -1
- package/dist/transformers.d.ts +3 -2
- package/dist/transformers.js +6 -0
- package/dist/transformers.js.map +1 -1
- package/package.json +1 -1
- package/src/diagnostic/{sdkDiagnosticFull.ts → diagnostic.ts} +10 -6
- package/src/diagnostic/index.ts +3 -5
- package/src/diagnostic/interface.ts +39 -0
- package/src/diagnostic/sdkDiagnostic.ts +110 -9
- package/src/interface/index.ts +1 -0
- package/src/interface/nodes.ts +3 -0
- package/src/interface/telemetry.ts +5 -0
- package/src/internal/apiService/driveTypes.ts +2698 -2529
- package/src/internal/download/controller.ts +13 -1
- package/src/internal/download/fileDownloader.ts +8 -1
- package/src/internal/nodes/apiService.test.ts +64 -0
- package/src/internal/nodes/apiService.ts +38 -17
- package/src/internal/nodes/debouncer.test.ts +25 -13
- package/src/internal/nodes/debouncer.ts +20 -4
- package/src/internal/nodes/extendedAttributes.ts +2 -2
- package/src/internal/nodes/index.ts +1 -8
- package/src/internal/nodes/nodesAccess.test.ts +17 -5
- package/src/internal/nodes/nodesAccess.ts +15 -5
- package/src/internal/nodes/nodesManagement.test.ts +3 -1
- package/src/internal/nodes/nodesManagement.ts +11 -5
- package/src/internal/photos/apiService.ts +12 -29
- package/src/internal/photos/upload.ts +19 -1
- package/src/internal/sharing/apiService.ts +2 -2
- package/src/internal/sharing/sharingManagement.ts +7 -4
- package/src/internal/sharingPublic/apiService.ts +23 -77
- package/src/internal/sharingPublic/index.ts +11 -10
- package/src/internal/sharingPublic/nodes.ts +33 -11
- package/src/internal/sharingPublic/session/apiService.ts +31 -9
- package/src/internal/sharingPublic/session/interface.ts +20 -0
- package/src/internal/sharingPublic/session/manager.ts +31 -8
- package/src/internal/sharingPublic/session/session.ts +10 -5
- package/src/internal/sharingPublic/shares.ts +7 -43
- package/src/internal/upload/controller.ts +16 -4
- package/src/internal/upload/fileUploader.ts +2 -2
- package/src/internal/upload/streamUploader.test.ts +46 -14
- package/src/internal/upload/streamUploader.ts +74 -21
- package/src/protonDriveClient.ts +25 -7
- package/src/protonDrivePublicLinkClient.ts +7 -4
- package/src/tests/telemetry.ts +6 -3
- package/src/transformers.ts +8 -0
- package/dist/diagnostic/sdkDiagnosticFull.js.map +0 -1
- package/dist/internal/sharingPublic/cryptoCache.d.ts +0 -15
- package/dist/internal/sharingPublic/cryptoCache.js +0 -44
- package/dist/internal/sharingPublic/cryptoCache.js.map +0 -1
- package/dist/internal/sharingPublic/cryptoService.d.ts +0 -8
- package/dist/internal/sharingPublic/cryptoService.js +0 -19
- package/dist/internal/sharingPublic/cryptoService.js.map +0 -1
- package/dist/internal/sharingPublic/interface.d.ts +0 -5
- package/dist/internal/sharingPublic/interface.js +0 -3
- package/dist/internal/sharingPublic/interface.js.map +0 -1
- package/src/internal/sharingPublic/cryptoCache.ts +0 -45
- package/src/internal/sharingPublic/cryptoService.ts +0 -22
- package/src/internal/sharingPublic/interface.ts +0 -5
|
@@ -133,7 +133,7 @@ describe('StreamUploader', () => {
|
|
|
133
133
|
metadata,
|
|
134
134
|
onFinish,
|
|
135
135
|
controller,
|
|
136
|
-
abortController
|
|
136
|
+
abortController,
|
|
137
137
|
);
|
|
138
138
|
});
|
|
139
139
|
|
|
@@ -146,10 +146,10 @@ describe('StreamUploader', () => {
|
|
|
146
146
|
|
|
147
147
|
const verifySuccess = async () => {
|
|
148
148
|
const result = await uploader.start(stream, thumbnails, onProgress);
|
|
149
|
-
|
|
149
|
+
|
|
150
150
|
expect(result).toEqual({
|
|
151
151
|
nodeRevisionUid: 'revisionUid',
|
|
152
|
-
nodeUid: 'nodeUid'
|
|
152
|
+
nodeUid: 'nodeUid',
|
|
153
153
|
});
|
|
154
154
|
|
|
155
155
|
const numberOfExpectedBlocks = Math.ceil(metadata.expectedSize / FILE_CHUNK_SIZE);
|
|
@@ -259,7 +259,7 @@ describe('StreamUploader', () => {
|
|
|
259
259
|
metadata,
|
|
260
260
|
onFinish,
|
|
261
261
|
controller,
|
|
262
|
-
abortController
|
|
262
|
+
abortController,
|
|
263
263
|
);
|
|
264
264
|
|
|
265
265
|
await verifySuccess();
|
|
@@ -288,7 +288,7 @@ describe('StreamUploader', () => {
|
|
|
288
288
|
metadata,
|
|
289
289
|
onFinish,
|
|
290
290
|
controller,
|
|
291
|
-
abortController
|
|
291
|
+
abortController,
|
|
292
292
|
);
|
|
293
293
|
|
|
294
294
|
await verifySuccess();
|
|
@@ -433,14 +433,6 @@ describe('StreamUploader', () => {
|
|
|
433
433
|
await verifyOnProgress([1024, 4 * 1024 * 1024, 2 * 1024 * 1024, 4 * 1024 * 1024]);
|
|
434
434
|
});
|
|
435
435
|
|
|
436
|
-
it('should handle abortion', async () => {
|
|
437
|
-
const error = new Error('Aborted');
|
|
438
|
-
const promise = uploader.start(stream, thumbnails, onProgress);
|
|
439
|
-
abortController.abort(error);
|
|
440
|
-
await promise;
|
|
441
|
-
expect(apiService.uploadBlock.mock.calls[0][4]?.aborted).toBe(true);
|
|
442
|
-
});
|
|
443
|
-
|
|
444
436
|
describe('verifyIntegrity', () => {
|
|
445
437
|
it('should report block verification error', async () => {
|
|
446
438
|
blockVerifier.verifyBlock = jest.fn().mockRejectedValue(new IntegrityError('Block verification error'));
|
|
@@ -473,7 +465,7 @@ describe('StreamUploader', () => {
|
|
|
473
465
|
} as UploadMetadata,
|
|
474
466
|
onFinish,
|
|
475
467
|
controller,
|
|
476
|
-
abortController
|
|
468
|
+
abortController,
|
|
477
469
|
);
|
|
478
470
|
|
|
479
471
|
await verifyFailure(
|
|
@@ -498,4 +490,44 @@ describe('StreamUploader', () => {
|
|
|
498
490
|
});
|
|
499
491
|
});
|
|
500
492
|
});
|
|
493
|
+
|
|
494
|
+
describe('abort', () => {
|
|
495
|
+
const thumbnails: Thumbnail[] = [];
|
|
496
|
+
let stream: ReadableStream<Uint8Array>;
|
|
497
|
+
let streamController: ReadableStreamDefaultController<Uint8Array>;
|
|
498
|
+
|
|
499
|
+
beforeEach(() => {
|
|
500
|
+
stream = new ReadableStream({
|
|
501
|
+
start(controller) {
|
|
502
|
+
streamController = controller;
|
|
503
|
+
},
|
|
504
|
+
});
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
it('should abort at the start', async () => {
|
|
508
|
+
const promise = uploader.start(stream, thumbnails);
|
|
509
|
+
abortController.abort();
|
|
510
|
+
await expect(promise).rejects.toThrow('Operation aborted');
|
|
511
|
+
});
|
|
512
|
+
|
|
513
|
+
it('should abort when encrypting blocks', async () => {
|
|
514
|
+
const promise = uploader.start(stream, thumbnails);
|
|
515
|
+
streamController.enqueue(new Uint8Array(FILE_CHUNK_SIZE));
|
|
516
|
+
streamController.enqueue(new Uint8Array(FILE_CHUNK_SIZE));
|
|
517
|
+
streamController.enqueue(new Uint8Array(FILE_CHUNK_SIZE));
|
|
518
|
+
abortController.abort();
|
|
519
|
+
await expect(promise).rejects.toThrow('Operation aborted');
|
|
520
|
+
});
|
|
521
|
+
|
|
522
|
+
it('should abort when uploading block', async () => {
|
|
523
|
+
apiService.uploadBlock = jest.fn().mockImplementation(async function () {
|
|
524
|
+
abortController.abort();
|
|
525
|
+
});
|
|
526
|
+
|
|
527
|
+
const promise = uploader.start(stream, thumbnails);
|
|
528
|
+
streamController.enqueue(new Uint8Array(FILE_CHUNK_SIZE));
|
|
529
|
+
|
|
530
|
+
await expect(promise).rejects.toThrow('Operation aborted');
|
|
531
|
+
});
|
|
532
|
+
});
|
|
501
533
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { c } from 'ttag';
|
|
2
2
|
|
|
3
3
|
import { Thumbnail, Logger, ThumbnailType, UploadMetadata } from '../../interface';
|
|
4
|
-
import { IntegrityError } from '../../errors';
|
|
4
|
+
import { AbortError, IntegrityError } from '../../errors';
|
|
5
5
|
import { LoggerWithPrefix } from '../../telemetry';
|
|
6
6
|
import { APIHTTPError, HTTPErrorCode, NotFoundAPIError } from '../apiService';
|
|
7
7
|
import { getErrorMessage } from '../errors';
|
|
@@ -59,7 +59,6 @@ export class StreamUploader {
|
|
|
59
59
|
|
|
60
60
|
protected digests: UploadDigests;
|
|
61
61
|
protected controller: UploadController;
|
|
62
|
-
protected abortController: AbortController;
|
|
63
62
|
|
|
64
63
|
protected encryptedThumbnails = new Map<ThumbnailType, EncryptedThumbnail>();
|
|
65
64
|
protected encryptedBlocks = new Map<number, EncryptedBlock>();
|
|
@@ -75,6 +74,9 @@ export class StreamUploader {
|
|
|
75
74
|
protected uploadedThumbnails: ({ type: ThumbnailType } & EncryptedBlockMetadata)[] = [];
|
|
76
75
|
protected uploadedBlocks: ({ index: number } & EncryptedBlockMetadata)[] = [];
|
|
77
76
|
|
|
77
|
+
// Error of the whole upload - either encryption or upload error.
|
|
78
|
+
protected error: unknown | undefined;
|
|
79
|
+
|
|
78
80
|
constructor(
|
|
79
81
|
protected telemetry: UploadTelemetry,
|
|
80
82
|
protected apiService: UploadAPIService,
|
|
@@ -85,7 +87,7 @@ export class StreamUploader {
|
|
|
85
87
|
protected metadata: UploadMetadata,
|
|
86
88
|
protected onFinish: (failure: boolean) => Promise<void>,
|
|
87
89
|
protected uploadController: UploadController,
|
|
88
|
-
protected
|
|
90
|
+
protected abortController: AbortController,
|
|
89
91
|
) {
|
|
90
92
|
this.telemetry = telemetry;
|
|
91
93
|
this.logger = telemetry.getLoggerForRevision(revisionDraft.nodeRevisionUid);
|
|
@@ -96,23 +98,16 @@ export class StreamUploader {
|
|
|
96
98
|
this.metadata = metadata;
|
|
97
99
|
this.onFinish = onFinish;
|
|
98
100
|
|
|
99
|
-
this.signal = signal;
|
|
100
|
-
this.abortController = new AbortController();
|
|
101
|
-
if (signal) {
|
|
102
|
-
signal.addEventListener('abort', () => {
|
|
103
|
-
this.abortController.abort();
|
|
104
|
-
});
|
|
105
|
-
}
|
|
106
|
-
|
|
107
101
|
this.digests = new UploadDigests();
|
|
108
102
|
this.controller = uploadController;
|
|
103
|
+
this.abortController = abortController;
|
|
109
104
|
}
|
|
110
105
|
|
|
111
106
|
async start(
|
|
112
107
|
stream: ReadableStream,
|
|
113
108
|
thumbnails: Thumbnail[],
|
|
114
109
|
onProgress?: (uploadedBytes: number) => void,
|
|
115
|
-
): Promise<{ nodeRevisionUid: string
|
|
110
|
+
): Promise<{ nodeRevisionUid: string; nodeUid: string }> {
|
|
116
111
|
let failure = false;
|
|
117
112
|
|
|
118
113
|
// File progress is tracked for telemetry - to track at what
|
|
@@ -157,9 +152,8 @@ export class StreamUploader {
|
|
|
157
152
|
|
|
158
153
|
return {
|
|
159
154
|
nodeRevisionUid: this.revisionDraft.nodeRevisionUid,
|
|
160
|
-
nodeUid: this.revisionDraft.nodeUid
|
|
161
|
-
}
|
|
162
|
-
|
|
155
|
+
nodeUid: this.revisionDraft.nodeUid,
|
|
156
|
+
};
|
|
163
157
|
}
|
|
164
158
|
|
|
165
159
|
private async encryptAndUploadBlocks(
|
|
@@ -183,8 +177,8 @@ export class StreamUploader {
|
|
|
183
177
|
void this.abortUpload(error);
|
|
184
178
|
});
|
|
185
179
|
|
|
186
|
-
while (!
|
|
187
|
-
await this.controller.
|
|
180
|
+
while (!this.isUploadAborted) {
|
|
181
|
+
await this.controller.waitWhilePaused();
|
|
188
182
|
await this.waitForUploadCapacityAndBufferedBlocks();
|
|
189
183
|
|
|
190
184
|
if (this.isEncryptionFullyFinished) {
|
|
@@ -198,6 +192,17 @@ export class StreamUploader {
|
|
|
198
192
|
}
|
|
199
193
|
}
|
|
200
194
|
|
|
195
|
+
// If the upload was aborted due to encryption or upload error, throw
|
|
196
|
+
// the original error (it is failing upload).
|
|
197
|
+
// If the upload was aborted due to abort signal, throw AbortError
|
|
198
|
+
// (it is aborted by the user).
|
|
199
|
+
if (this.error) {
|
|
200
|
+
throw this.error;
|
|
201
|
+
}
|
|
202
|
+
if (this.abortController.signal.aborted) {
|
|
203
|
+
throw new AbortError();
|
|
204
|
+
}
|
|
205
|
+
|
|
201
206
|
this.logger.debug(`All blocks uploading, waiting for them to finish`);
|
|
202
207
|
// Technically this is finished as while-block above will break
|
|
203
208
|
// when encryption is finished. But in case of error there could
|
|
@@ -233,6 +238,10 @@ export class StreamUploader {
|
|
|
233
238
|
}
|
|
234
239
|
|
|
235
240
|
for (const thumbnail of thumbnails) {
|
|
241
|
+
if (this.isUploadAborted) {
|
|
242
|
+
break;
|
|
243
|
+
}
|
|
244
|
+
|
|
236
245
|
this.logger.debug(`Encrypting thumbnail ${thumbnail.type}`);
|
|
237
246
|
const encryptedThumbnail = await this.cryptoService.encryptThumbnail(
|
|
238
247
|
this.revisionDraft.nodeKeys,
|
|
@@ -251,9 +260,13 @@ export class StreamUploader {
|
|
|
251
260
|
|
|
252
261
|
this.digests.update(block);
|
|
253
262
|
|
|
254
|
-
await this.controller.
|
|
263
|
+
await this.controller.waitWhilePaused();
|
|
255
264
|
await this.waitForBufferCapacity();
|
|
256
265
|
|
|
266
|
+
if (this.isUploadAborted) {
|
|
267
|
+
break;
|
|
268
|
+
}
|
|
269
|
+
|
|
257
270
|
this.logger.debug(`Encrypting block ${index}`);
|
|
258
271
|
let attempt = 0;
|
|
259
272
|
let integrityError = false;
|
|
@@ -272,6 +285,11 @@ export class StreamUploader {
|
|
|
272
285
|
void this.telemetry.logBlockVerificationError(true);
|
|
273
286
|
}
|
|
274
287
|
} catch (error: unknown) {
|
|
288
|
+
// Do not retry or report anything if the upload was aborted.
|
|
289
|
+
if (error instanceof AbortError) {
|
|
290
|
+
throw error;
|
|
291
|
+
}
|
|
292
|
+
|
|
275
293
|
if (error instanceof IntegrityError) {
|
|
276
294
|
integrityError = true;
|
|
277
295
|
}
|
|
@@ -399,6 +417,11 @@ export class StreamUploader {
|
|
|
399
417
|
});
|
|
400
418
|
break;
|
|
401
419
|
} catch (error: unknown) {
|
|
420
|
+
// Do not retry or report anything if the upload was aborted.
|
|
421
|
+
if (error instanceof AbortError) {
|
|
422
|
+
throw error;
|
|
423
|
+
}
|
|
424
|
+
|
|
402
425
|
if (blockProgress !== 0) {
|
|
403
426
|
onProgress?.(-blockProgress);
|
|
404
427
|
blockProgress = 0;
|
|
@@ -461,6 +484,11 @@ export class StreamUploader {
|
|
|
461
484
|
});
|
|
462
485
|
break;
|
|
463
486
|
} catch (error: unknown) {
|
|
487
|
+
// Do not retry or report anything if the upload was aborted.
|
|
488
|
+
if (error instanceof AbortError) {
|
|
489
|
+
throw error;
|
|
490
|
+
}
|
|
491
|
+
|
|
464
492
|
if (blockProgress !== 0) {
|
|
465
493
|
onProgress?.(-blockProgress);
|
|
466
494
|
blockProgress = 0;
|
|
@@ -510,7 +538,17 @@ export class StreamUploader {
|
|
|
510
538
|
|
|
511
539
|
private async waitForBufferCapacity() {
|
|
512
540
|
if (this.encryptedBlocks.size >= MAX_BUFFERED_BLOCKS) {
|
|
513
|
-
|
|
541
|
+
try {
|
|
542
|
+
await waitForCondition(
|
|
543
|
+
() => this.encryptedBlocks.size < MAX_BUFFERED_BLOCKS,
|
|
544
|
+
this.abortController.signal,
|
|
545
|
+
);
|
|
546
|
+
} catch (error: unknown) {
|
|
547
|
+
if (error instanceof AbortError) {
|
|
548
|
+
return;
|
|
549
|
+
}
|
|
550
|
+
throw error;
|
|
551
|
+
}
|
|
514
552
|
}
|
|
515
553
|
}
|
|
516
554
|
|
|
@@ -518,7 +556,17 @@ export class StreamUploader {
|
|
|
518
556
|
while (this.ongoingUploads.size >= MAX_UPLOADING_BLOCKS) {
|
|
519
557
|
await Promise.race(this.ongoingUploads.values().map(({ uploadPromise }) => uploadPromise));
|
|
520
558
|
}
|
|
521
|
-
|
|
559
|
+
try {
|
|
560
|
+
await waitForCondition(
|
|
561
|
+
() => this.encryptedBlocks.size > 0 || this.encryptionFinished,
|
|
562
|
+
this.abortController.signal,
|
|
563
|
+
);
|
|
564
|
+
} catch (error: unknown) {
|
|
565
|
+
if (error instanceof AbortError) {
|
|
566
|
+
return;
|
|
567
|
+
}
|
|
568
|
+
throw error;
|
|
569
|
+
}
|
|
522
570
|
}
|
|
523
571
|
|
|
524
572
|
protected verifyIntegrity(thumbnails: Thumbnail[]) {
|
|
@@ -573,9 +621,14 @@ export class StreamUploader {
|
|
|
573
621
|
}
|
|
574
622
|
|
|
575
623
|
private async abortUpload(error: unknown) {
|
|
576
|
-
if (this.
|
|
624
|
+
if (this.isUploadAborted) {
|
|
577
625
|
return;
|
|
578
626
|
}
|
|
627
|
+
this.error = error;
|
|
579
628
|
this.abortController.abort(error);
|
|
580
629
|
}
|
|
630
|
+
|
|
631
|
+
private get isUploadAborted(): boolean {
|
|
632
|
+
return !!this.error || this.abortController.signal.aborted;
|
|
633
|
+
}
|
|
581
634
|
}
|
package/src/protonDriveClient.ts
CHANGED
|
@@ -7,6 +7,7 @@ import {
|
|
|
7
7
|
MaybeNode,
|
|
8
8
|
MaybeMissingNode,
|
|
9
9
|
NodeResult,
|
|
10
|
+
NodeResultWithNewUid,
|
|
10
11
|
Revision,
|
|
11
12
|
RevisionOrUid,
|
|
12
13
|
ShareNodeSettings,
|
|
@@ -28,6 +29,7 @@ import {
|
|
|
28
29
|
ThumbnailResult,
|
|
29
30
|
SDKEvent,
|
|
30
31
|
NodeType,
|
|
32
|
+
MemberRole,
|
|
31
33
|
} from './interface';
|
|
32
34
|
import {
|
|
33
35
|
getUid,
|
|
@@ -36,6 +38,7 @@ import {
|
|
|
36
38
|
convertInternalNodeIterator,
|
|
37
39
|
convertInternalMissingNodeIterator,
|
|
38
40
|
convertInternalNode,
|
|
41
|
+
convertInternalRevisionIterator,
|
|
39
42
|
} from './transformers';
|
|
40
43
|
import { Telemetry } from './telemetry';
|
|
41
44
|
import { DriveAPIService } from './internal/apiService';
|
|
@@ -68,7 +71,7 @@ export class ProtonDriveClient {
|
|
|
68
71
|
private download: ReturnType<typeof initDownloadModule>;
|
|
69
72
|
private upload: ReturnType<typeof initUploadModule>;
|
|
70
73
|
private devices: ReturnType<typeof initDevicesModule>;
|
|
71
|
-
private
|
|
74
|
+
private publicSessionManager: SharingPublicSessionManager;
|
|
72
75
|
|
|
73
76
|
public experimental: {
|
|
74
77
|
/**
|
|
@@ -93,6 +96,11 @@ export class ProtonDriveClient {
|
|
|
93
96
|
isCustomPasswordProtected: boolean;
|
|
94
97
|
isLegacy: boolean;
|
|
95
98
|
vendorType: number;
|
|
99
|
+
directAccess?: {
|
|
100
|
+
nodeUid: string;
|
|
101
|
+
directRole: MemberRole;
|
|
102
|
+
publicRole: MemberRole;
|
|
103
|
+
};
|
|
96
104
|
}>;
|
|
97
105
|
/**
|
|
98
106
|
* Experimental feature to authenticate a public link and
|
|
@@ -184,7 +192,13 @@ export class ProtonDriveClient {
|
|
|
184
192
|
latestEventIdProvider,
|
|
185
193
|
);
|
|
186
194
|
|
|
187
|
-
this.
|
|
195
|
+
this.publicSessionManager = new SharingPublicSessionManager(
|
|
196
|
+
telemetry,
|
|
197
|
+
httpClient,
|
|
198
|
+
cryptoModule,
|
|
199
|
+
srpModule,
|
|
200
|
+
apiService,
|
|
201
|
+
);
|
|
188
202
|
|
|
189
203
|
this.experimental = {
|
|
190
204
|
getNodeUrl: async (nodeUid: NodeOrUid) => {
|
|
@@ -201,11 +215,14 @@ export class ProtonDriveClient {
|
|
|
201
215
|
},
|
|
202
216
|
getPublicLinkInfo: async (url: string) => {
|
|
203
217
|
this.logger.info(`Getting info for public link ${url}`);
|
|
204
|
-
return this.
|
|
218
|
+
return this.publicSessionManager.getInfo(url);
|
|
205
219
|
},
|
|
206
220
|
authPublicLink: async (url: string, customPassword?: string) => {
|
|
207
221
|
this.logger.info(`Authenticating public link ${url}`);
|
|
208
|
-
const { httpClient, token,
|
|
222
|
+
const { httpClient, token, shareKey, rootUid } = await this.publicSessionManager.auth(
|
|
223
|
+
url,
|
|
224
|
+
customPassword,
|
|
225
|
+
);
|
|
209
226
|
return new ProtonDrivePublicLinkClient({
|
|
210
227
|
httpClient,
|
|
211
228
|
account,
|
|
@@ -215,7 +232,8 @@ export class ProtonDriveClient {
|
|
|
215
232
|
telemetry,
|
|
216
233
|
url,
|
|
217
234
|
token,
|
|
218
|
-
|
|
235
|
+
publicShareKey: shareKey,
|
|
236
|
+
publicRootNodeUid: rootUid,
|
|
219
237
|
});
|
|
220
238
|
},
|
|
221
239
|
};
|
|
@@ -408,7 +426,7 @@ export class ProtonDriveClient {
|
|
|
408
426
|
nodeUids: NodeOrUid[],
|
|
409
427
|
newParentNodeUid: NodeOrUid,
|
|
410
428
|
signal?: AbortSignal,
|
|
411
|
-
): AsyncGenerator<
|
|
429
|
+
): AsyncGenerator<NodeResultWithNewUid> {
|
|
412
430
|
this.logger.info(`Copying ${nodeUids.length} nodes to ${getUid(newParentNodeUid)}`);
|
|
413
431
|
yield* this.nodes.management.copyNodes(getUids(nodeUids), getUid(newParentNodeUid), signal);
|
|
414
432
|
}
|
|
@@ -507,7 +525,7 @@ export class ProtonDriveClient {
|
|
|
507
525
|
*/
|
|
508
526
|
async *iterateRevisions(nodeUid: NodeOrUid, signal?: AbortSignal): AsyncGenerator<Revision> {
|
|
509
527
|
this.logger.info(`Iterating revisions of ${getUid(nodeUid)}`);
|
|
510
|
-
yield* this.nodes.revisions.iterateRevisions(getUid(nodeUid), signal);
|
|
528
|
+
yield* convertInternalRevisionIterator(this.nodes.revisions.iterateRevisions(getUid(nodeUid), signal));
|
|
511
529
|
}
|
|
512
530
|
|
|
513
531
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { MemoryCache } from './cache';
|
|
2
2
|
import { getConfig } from './config';
|
|
3
|
-
import { DriveCrypto, OpenPGPCrypto, SRPModule, SessionKey } from './crypto';
|
|
3
|
+
import { DriveCrypto, OpenPGPCrypto, PrivateKey, SRPModule, SessionKey } from './crypto';
|
|
4
4
|
import {
|
|
5
5
|
ProtonDriveHTTPClient,
|
|
6
6
|
ProtonDriveTelemetry,
|
|
@@ -74,7 +74,8 @@ export class ProtonDrivePublicLinkClient {
|
|
|
74
74
|
telemetry,
|
|
75
75
|
url,
|
|
76
76
|
token,
|
|
77
|
-
|
|
77
|
+
publicShareKey,
|
|
78
|
+
publicRootNodeUid,
|
|
78
79
|
}: {
|
|
79
80
|
httpClient: ProtonDriveHTTPClient;
|
|
80
81
|
account: ProtonDriveAccount;
|
|
@@ -84,7 +85,8 @@ export class ProtonDrivePublicLinkClient {
|
|
|
84
85
|
telemetry?: ProtonDriveTelemetry;
|
|
85
86
|
url: string;
|
|
86
87
|
token: string;
|
|
87
|
-
|
|
88
|
+
publicShareKey: PrivateKey;
|
|
89
|
+
publicRootNodeUid: string;
|
|
88
90
|
}) {
|
|
89
91
|
if (!telemetry) {
|
|
90
92
|
telemetry = new Telemetry();
|
|
@@ -115,7 +117,8 @@ export class ProtonDrivePublicLinkClient {
|
|
|
115
117
|
account,
|
|
116
118
|
url,
|
|
117
119
|
token,
|
|
118
|
-
|
|
120
|
+
publicShareKey,
|
|
121
|
+
publicRootNodeUid,
|
|
119
122
|
);
|
|
120
123
|
this.download = initDownloadModule(
|
|
121
124
|
telemetry,
|
package/src/tests/telemetry.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { ProtonDriveTelemetry } from '../interface';
|
|
1
|
+
import { Logger, ProtonDriveTelemetry } from '../interface';
|
|
2
2
|
import { getMockLogger } from './logger';
|
|
3
3
|
|
|
4
|
-
export function getMockTelemetry(): ProtonDriveTelemetry {
|
|
4
|
+
export function getMockTelemetry(): ProtonDriveTelemetry & { mockLogger: Logger } {
|
|
5
|
+
const mockLogger = getMockLogger();
|
|
6
|
+
|
|
5
7
|
return {
|
|
6
|
-
|
|
8
|
+
mockLogger,
|
|
9
|
+
getLogger: () => mockLogger,
|
|
7
10
|
recordMetric: jest.fn(),
|
|
8
11
|
};
|
|
9
12
|
}
|
package/src/transformers.ts
CHANGED
|
@@ -121,6 +121,14 @@ export function convertInternalNode(node: InternalPartialNode): PublicMaybeNode
|
|
|
121
121
|
} as PublicNodeEntity);
|
|
122
122
|
}
|
|
123
123
|
|
|
124
|
+
export async function* convertInternalRevisionIterator(
|
|
125
|
+
revisionIterator: AsyncGenerator<InternalRevision>,
|
|
126
|
+
): AsyncGenerator<PublicRevision> {
|
|
127
|
+
for await (const revision of revisionIterator) {
|
|
128
|
+
yield convertInternalRevision(revision);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
124
132
|
function convertInternalRevision(revision: InternalRevision): PublicRevision {
|
|
125
133
|
return {
|
|
126
134
|
uid: revision.uid,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sdkDiagnosticFull.js","sourceRoot":"","sources":["../../src/diagnostic/sdkDiagnosticFull.ts"],"names":[],"mappings":";;;AAIA,mDAAgD;AAEhD;;;GAGG;AACH,MAAa,iBAAiB;IAEd;IACA;IACA;IAHZ,YACY,UAAsB,EACtB,SAA8B,EAC9B,UAAgC;QAFhC,eAAU,GAAV,UAAU,CAAY;QACtB,cAAS,GAAT,SAAS,CAAqB;QAC9B,eAAU,GAAV,UAAU,CAAsB;QAExC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,CAAC,aAAa,CAAC,OAA2B;QAC5C,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC;IACpE,CAAC;IAED,KAAK,CAAC,CAAC,cAAc,CAAC,IAAe,EAAE,OAA2B;QAC9D,KAAK,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IAC3E,CAAC;IAEO,KAAK,CAAC,CAAC,WAAW,CAAC,SAA2C;QAClE,KAAK,CAAC,CAAC,IAAA,6BAAa,EAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,EAAE,EAAE,eAAe,EAAE,IAAI,EAAE,CAAC,CAAC;IACzF,CAAC;IAEO,KAAK,CAAC,CAAC,iBAAiB;QAC5B,KAAK,CAAC,CAAC,IAAA,6BAAa,EAAC,IAAI,CAAC,SAAS,CAAC,aAAa,EAAE,EAAE,IAAI,CAAC,UAAU,CAAC,aAAa,EAAE,CAAC,CAAC;IAC1F,CAAC;CACJ;AA1BD,8CA0BC"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { PrivateKey } from '../../crypto';
|
|
2
|
-
import { ProtonDriveCryptoCache, Logger } from '../../interface';
|
|
3
|
-
/**
|
|
4
|
-
* Provides caching for public link crypto material.
|
|
5
|
-
*
|
|
6
|
-
* The cache is responsible for serialising and deserialising public link
|
|
7
|
-
* crypto material.
|
|
8
|
-
*/
|
|
9
|
-
export declare class SharingPublicCryptoCache {
|
|
10
|
-
private logger;
|
|
11
|
-
private driveCache;
|
|
12
|
-
constructor(logger: Logger, driveCache: ProtonDriveCryptoCache);
|
|
13
|
-
setShareKey(shareKey: PrivateKey): Promise<void>;
|
|
14
|
-
getShareKey(): Promise<PrivateKey>;
|
|
15
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SharingPublicCryptoCache = void 0;
|
|
4
|
-
/**
|
|
5
|
-
* Provides caching for public link crypto material.
|
|
6
|
-
*
|
|
7
|
-
* The cache is responsible for serialising and deserialising public link
|
|
8
|
-
* crypto material.
|
|
9
|
-
*/
|
|
10
|
-
class SharingPublicCryptoCache {
|
|
11
|
-
logger;
|
|
12
|
-
driveCache;
|
|
13
|
-
constructor(logger, driveCache) {
|
|
14
|
-
this.logger = logger;
|
|
15
|
-
this.driveCache = driveCache;
|
|
16
|
-
this.logger = logger;
|
|
17
|
-
this.driveCache = driveCache;
|
|
18
|
-
}
|
|
19
|
-
async setShareKey(shareKey) {
|
|
20
|
-
await this.driveCache.setEntity(getShareKeyCacheKey(), {
|
|
21
|
-
publicShareKey: {
|
|
22
|
-
key: shareKey,
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
async getShareKey() {
|
|
27
|
-
const shareKeyData = await this.driveCache.getEntity(getShareKeyCacheKey());
|
|
28
|
-
if (!shareKeyData.publicShareKey) {
|
|
29
|
-
try {
|
|
30
|
-
await this.driveCache.removeEntities([getShareKeyCacheKey()]);
|
|
31
|
-
}
|
|
32
|
-
catch (removingError) {
|
|
33
|
-
this.logger.warn(`Failed to remove corrupted public share key from the cache: ${removingError instanceof Error ? removingError.message : removingError}`);
|
|
34
|
-
}
|
|
35
|
-
throw new Error('Failed to deserialize public share key');
|
|
36
|
-
}
|
|
37
|
-
return shareKeyData.publicShareKey.key;
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
exports.SharingPublicCryptoCache = SharingPublicCryptoCache;
|
|
41
|
-
function getShareKeyCacheKey() {
|
|
42
|
-
return 'publicShareKey';
|
|
43
|
-
}
|
|
44
|
-
//# sourceMappingURL=cryptoCache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cryptoCache.js","sourceRoot":"","sources":["../../../src/internal/sharingPublic/cryptoCache.ts"],"names":[],"mappings":";;;AAGA;;;;;GAKG;AACH,MAAa,wBAAwB;IAErB;IACA;IAFZ,YACY,MAAc,EACd,UAAkC;QADlC,WAAM,GAAN,MAAM,CAAQ;QACd,eAAU,GAAV,UAAU,CAAwB;QAE1C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,QAAoB;QAClC,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,mBAAmB,EAAE,EAAE;YACnD,cAAc,EAAE;gBACZ,GAAG,EAAE,QAAQ;aAChB;SACJ,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,WAAW;QACb,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,mBAAmB,EAAE,CAAC,CAAC;QAC5E,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;YAC/B,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;YAClE,CAAC;YAAC,OAAO,aAAsB,EAAE,CAAC;gBAC9B,IAAI,CAAC,MAAM,CAAC,IAAI,CACZ,+DAA+D,aAAa,YAAY,KAAK,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,aAAa,EAAE,CAC1I,CAAC;YACN,CAAC;YACD,MAAM,IAAI,KAAK,CAAC,wCAAwC,CAAC,CAAC;QAC9D,CAAC;QACD,OAAO,YAAY,CAAC,cAAc,CAAC,GAAG,CAAC;IAC3C,CAAC;CACJ;AA/BD,4DA+BC;AAED,SAAS,mBAAmB;IACxB,OAAO,gBAAgB,CAAC;AAC5B,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { DriveCrypto, PrivateKey } from '../../crypto';
|
|
2
|
-
import { EncryptedShareCrypto } from './interface';
|
|
3
|
-
export declare class SharingPublicCryptoService {
|
|
4
|
-
private driveCrypto;
|
|
5
|
-
private password;
|
|
6
|
-
constructor(driveCrypto: DriveCrypto, password: string);
|
|
7
|
-
decryptPublicLinkShareKey(encryptedShare: EncryptedShareCrypto): Promise<PrivateKey>;
|
|
8
|
-
}
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.SharingPublicCryptoService = void 0;
|
|
4
|
-
class SharingPublicCryptoService {
|
|
5
|
-
driveCrypto;
|
|
6
|
-
password;
|
|
7
|
-
constructor(driveCrypto, password) {
|
|
8
|
-
this.driveCrypto = driveCrypto;
|
|
9
|
-
this.password = password;
|
|
10
|
-
this.driveCrypto = driveCrypto;
|
|
11
|
-
this.password = password;
|
|
12
|
-
}
|
|
13
|
-
async decryptPublicLinkShareKey(encryptedShare) {
|
|
14
|
-
const { key: shareKey } = await this.driveCrypto.decryptKeyWithSrpPassword(this.password, encryptedShare.base64UrlPasswordSalt, encryptedShare.armoredKey, encryptedShare.armoredPassphrase);
|
|
15
|
-
return shareKey;
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
exports.SharingPublicCryptoService = SharingPublicCryptoService;
|
|
19
|
-
//# sourceMappingURL=cryptoService.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cryptoService.js","sourceRoot":"","sources":["../../../src/internal/sharingPublic/cryptoService.ts"],"names":[],"mappings":";;;AAGA,MAAa,0BAA0B;IAEvB;IACA;IAFZ,YACY,WAAwB,EACxB,QAAgB;QADhB,gBAAW,GAAX,WAAW,CAAa;QACxB,aAAQ,GAAR,QAAQ,CAAQ;QAExB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,yBAAyB,CAAC,cAAoC;QAChE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,yBAAyB,CACtE,IAAI,CAAC,QAAQ,EACb,cAAc,CAAC,qBAAqB,EACpC,cAAc,CAAC,UAAU,EACzB,cAAc,CAAC,iBAAiB,CACnC,CAAC;QACF,OAAO,QAAQ,CAAC;IACpB,CAAC;CACJ;AAlBD,gEAkBC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"interface.js","sourceRoot":"","sources":["../../../src/internal/sharingPublic/interface.ts"],"names":[],"mappings":""}
|
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
import { PrivateKey } from '../../crypto';
|
|
2
|
-
import { ProtonDriveCryptoCache, Logger } from '../../interface';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Provides caching for public link crypto material.
|
|
6
|
-
*
|
|
7
|
-
* The cache is responsible for serialising and deserialising public link
|
|
8
|
-
* crypto material.
|
|
9
|
-
*/
|
|
10
|
-
export class SharingPublicCryptoCache {
|
|
11
|
-
constructor(
|
|
12
|
-
private logger: Logger,
|
|
13
|
-
private driveCache: ProtonDriveCryptoCache,
|
|
14
|
-
) {
|
|
15
|
-
this.logger = logger;
|
|
16
|
-
this.driveCache = driveCache;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
async setShareKey(shareKey: PrivateKey): Promise<void> {
|
|
20
|
-
await this.driveCache.setEntity(getShareKeyCacheKey(), {
|
|
21
|
-
publicShareKey: {
|
|
22
|
-
key: shareKey,
|
|
23
|
-
},
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
async getShareKey(): Promise<PrivateKey> {
|
|
28
|
-
const shareKeyData = await this.driveCache.getEntity(getShareKeyCacheKey());
|
|
29
|
-
if (!shareKeyData.publicShareKey) {
|
|
30
|
-
try {
|
|
31
|
-
await this.driveCache.removeEntities([getShareKeyCacheKey()]);
|
|
32
|
-
} catch (removingError: unknown) {
|
|
33
|
-
this.logger.warn(
|
|
34
|
-
`Failed to remove corrupted public share key from the cache: ${removingError instanceof Error ? removingError.message : removingError}`,
|
|
35
|
-
);
|
|
36
|
-
}
|
|
37
|
-
throw new Error('Failed to deserialize public share key');
|
|
38
|
-
}
|
|
39
|
-
return shareKeyData.publicShareKey.key;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
function getShareKeyCacheKey() {
|
|
44
|
-
return 'publicShareKey';
|
|
45
|
-
}
|