@protontech/drive-sdk 0.1.0 → 0.1.2
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/cache/memoryCache.js +0 -1
- package/dist/cache/memoryCache.js.map +1 -1
- package/dist/cache/memoryCache.test.js +2 -4
- package/dist/cache/memoryCache.test.js.map +1 -1
- package/dist/cache/nullCache.js +0 -1
- package/dist/cache/nullCache.js.map +1 -1
- package/dist/crypto/driveCrypto.d.ts +2 -5
- package/dist/crypto/driveCrypto.js +7 -12
- package/dist/crypto/driveCrypto.js.map +1 -1
- package/dist/crypto/driveCrypto.test.js +14 -14
- package/dist/crypto/openPGPCrypto.js +3 -3
- package/dist/crypto/openPGPCrypto.js.map +1 -1
- package/dist/diagnostic/eventsGenerator.js +1 -1
- package/dist/diagnostic/eventsGenerator.js.map +1 -1
- package/dist/diagnostic/httpClient.d.ts +1 -1
- package/dist/diagnostic/httpClient.js.map +1 -1
- package/dist/diagnostic/index.d.ts +3 -3
- package/dist/diagnostic/index.js.map +1 -1
- package/dist/diagnostic/integrityVerificationStream.js +1 -1
- package/dist/diagnostic/integrityVerificationStream.js.map +1 -1
- package/dist/diagnostic/interface.d.ts +2 -2
- package/dist/diagnostic/sdkDiagnostic.d.ts +3 -3
- package/dist/diagnostic/sdkDiagnostic.js +8 -2
- package/dist/diagnostic/sdkDiagnostic.js.map +1 -1
- package/dist/diagnostic/sdkDiagnosticFull.d.ts +4 -4
- package/dist/diagnostic/sdkDiagnosticFull.js.map +1 -1
- package/dist/diagnostic/telemetry.js.map +1 -1
- package/dist/diagnostic/zipGenerators.js +2 -2
- package/dist/diagnostic/zipGenerators.js.map +1 -1
- package/dist/diagnostic/zipGenerators.test.js +1 -1
- package/dist/diagnostic/zipGenerators.test.js.map +1 -1
- package/dist/interface/events.d.ts +2 -4
- package/dist/interface/events.js.map +1 -1
- package/dist/interface/index.d.ts +5 -5
- package/dist/interface/index.js +0 -1
- package/dist/interface/index.js.map +1 -1
- package/dist/interface/result.js.map +1 -1
- package/dist/interface/sharing.d.ts +1 -0
- package/dist/interface/sharing.js.map +1 -1
- package/dist/interface/telemetry.js +0 -8
- package/dist/interface/telemetry.js.map +1 -1
- package/dist/interface/thumbnail.js.map +1 -1
- package/dist/interface/upload.d.ts +1 -1
- package/dist/internal/apiService/apiService.d.ts +1 -1
- package/dist/internal/apiService/apiService.js +7 -11
- package/dist/internal/apiService/apiService.js.map +1 -1
- package/dist/internal/apiService/apiService.test.js +55 -48
- package/dist/internal/apiService/apiService.test.js.map +1 -1
- package/dist/internal/apiService/coreTypes.d.ts +2356 -2356
- package/dist/internal/apiService/driveTypes.d.ts +1680 -1680
- package/dist/internal/apiService/errors.js +14 -8
- package/dist/internal/apiService/errors.js.map +1 -1
- package/dist/internal/apiService/errors.test.js +17 -12
- package/dist/internal/apiService/errors.test.js.map +1 -1
- package/dist/internal/apiService/transformers.d.ts +1 -1
- package/dist/internal/apiService/transformers.js +1 -1
- package/dist/internal/asyncIteratorMap.test.js +2 -2
- package/dist/internal/asyncIteratorMap.test.js.map +1 -1
- package/dist/internal/asyncIteratorRace.d.ts +13 -0
- package/dist/internal/asyncIteratorRace.js +59 -0
- package/dist/internal/asyncIteratorRace.js.map +1 -0
- package/dist/internal/asyncIteratorRace.test.d.ts +1 -0
- package/dist/internal/asyncIteratorRace.test.js +119 -0
- package/dist/internal/asyncIteratorRace.test.js.map +1 -0
- package/dist/internal/batch.d.ts +1 -0
- package/dist/internal/batch.js +12 -0
- package/dist/internal/batch.js.map +1 -0
- package/dist/internal/batch.test.d.ts +1 -0
- package/dist/internal/batch.test.js +41 -0
- package/dist/internal/batch.test.js.map +1 -0
- package/dist/internal/batchLoading.js.map +1 -1
- package/dist/internal/batchLoading.test.js +13 -13
- package/dist/internal/batchLoading.test.js.map +1 -1
- package/dist/internal/devices/apiService.d.ts +3 -3
- package/dist/internal/devices/apiService.js +2 -2
- package/dist/internal/devices/apiService.js.map +1 -1
- package/dist/internal/devices/cryptoService.js +1 -2
- package/dist/internal/devices/cryptoService.js.map +1 -1
- package/dist/internal/devices/index.d.ts +5 -5
- package/dist/internal/devices/index.js.map +1 -1
- package/dist/internal/devices/interface.d.ts +3 -3
- package/dist/internal/devices/manager.js +2 -2
- package/dist/internal/devices/manager.js.map +1 -1
- package/dist/internal/devices/manager.test.js +38 -7
- package/dist/internal/devices/manager.test.js.map +1 -1
- package/dist/internal/download/apiService.d.ts +4 -4
- package/dist/internal/download/apiService.js +0 -1
- package/dist/internal/download/apiService.js.map +1 -1
- package/dist/internal/download/cryptoService.d.ts +4 -4
- package/dist/internal/download/cryptoService.js +6 -5
- package/dist/internal/download/cryptoService.js.map +1 -1
- package/dist/internal/download/fileDownloader.d.ts +4 -4
- package/dist/internal/download/fileDownloader.js +3 -2
- package/dist/internal/download/fileDownloader.js.map +1 -1
- package/dist/internal/download/fileDownloader.test.js +1 -1
- package/dist/internal/download/fileDownloader.test.js.map +1 -1
- package/dist/internal/download/index.d.ts +5 -5
- package/dist/internal/download/index.js +5 -5
- package/dist/internal/download/index.js.map +1 -1
- package/dist/internal/download/interface.d.ts +3 -4
- package/dist/internal/download/telemetry.d.ts +3 -3
- package/dist/internal/download/telemetry.js +4 -2
- package/dist/internal/download/telemetry.js.map +1 -1
- package/dist/internal/download/telemetry.test.js +8 -8
- package/dist/internal/download/telemetry.test.js.map +1 -1
- package/dist/internal/download/thumbnailDownloader.d.ts +4 -4
- package/dist/internal/download/thumbnailDownloader.js +6 -6
- package/dist/internal/download/thumbnailDownloader.js.map +1 -1
- package/dist/internal/download/thumbnailDownloader.test.js.map +1 -1
- package/dist/internal/errors.d.ts +1 -1
- package/dist/internal/errors.js +1 -3
- package/dist/internal/errors.js.map +1 -1
- package/dist/internal/events/apiService.d.ts +2 -2
- package/dist/internal/events/apiService.js +9 -5
- package/dist/internal/events/apiService.js.map +1 -1
- package/dist/internal/events/coreEventManager.d.ts +3 -3
- package/dist/internal/events/coreEventManager.js.map +1 -1
- package/dist/internal/events/coreEventManager.test.js +14 -14
- package/dist/internal/events/eventManager.d.ts +2 -1
- package/dist/internal/events/eventManager.js +9 -1
- package/dist/internal/events/eventManager.js.map +1 -1
- package/dist/internal/events/eventManager.test.js +84 -60
- package/dist/internal/events/eventManager.test.js.map +1 -1
- package/dist/internal/events/index.d.ts +10 -9
- package/dist/internal/events/index.js +38 -32
- package/dist/internal/events/index.js.map +1 -1
- package/dist/internal/events/interface.d.ts +1 -1
- package/dist/internal/events/interface.js +0 -1
- package/dist/internal/events/interface.js.map +1 -1
- package/dist/internal/events/volumeEventManager.d.ts +3 -3
- package/dist/internal/events/volumeEventManager.js.map +1 -1
- package/dist/internal/events/volumeEventManager.test.js +55 -55
- package/dist/internal/events/volumeEventManager.test.js.map +1 -1
- package/dist/internal/nodes/apiService.d.ts +4 -3
- package/dist/internal/nodes/apiService.js +36 -15
- package/dist/internal/nodes/apiService.js.map +1 -1
- package/dist/internal/nodes/apiService.test.js +60 -41
- package/dist/internal/nodes/apiService.test.js.map +1 -1
- package/dist/internal/nodes/cache.d.ts +5 -5
- package/dist/internal/nodes/cache.js +14 -7
- package/dist/internal/nodes/cache.js.map +1 -1
- package/dist/internal/nodes/cache.test.js +31 -9
- package/dist/internal/nodes/cache.test.js.map +1 -1
- package/dist/internal/nodes/cryptoCache.d.ts +2 -2
- package/dist/internal/nodes/cryptoCache.js.map +1 -1
- package/dist/internal/nodes/cryptoCache.test.js +24 -4
- package/dist/internal/nodes/cryptoCache.test.js.map +1 -1
- package/dist/internal/nodes/cryptoService.d.ts +3 -3
- package/dist/internal/nodes/cryptoService.js +11 -17
- package/dist/internal/nodes/cryptoService.js.map +1 -1
- package/dist/internal/nodes/cryptoService.test.js +320 -241
- package/dist/internal/nodes/cryptoService.test.js.map +1 -1
- package/dist/internal/nodes/events.d.ts +3 -3
- package/dist/internal/nodes/events.js +7 -7
- package/dist/internal/nodes/events.js.map +1 -1
- package/dist/internal/nodes/events.test.js +27 -21
- package/dist/internal/nodes/events.test.js.map +1 -1
- package/dist/internal/nodes/extendedAttributes.d.ts +1 -1
- package/dist/internal/nodes/extendedAttributes.js +3 -1
- package/dist/internal/nodes/extendedAttributes.js.map +1 -1
- package/dist/internal/nodes/extendedAttributes.test.js +7 -10
- package/dist/internal/nodes/extendedAttributes.test.js.map +1 -1
- package/dist/internal/nodes/index.d.ts +10 -10
- package/dist/internal/nodes/index.js.map +1 -1
- package/dist/internal/nodes/index.test.d.ts +1 -0
- package/dist/internal/nodes/index.test.js +106 -0
- package/dist/internal/nodes/index.test.js.map +1 -0
- package/dist/internal/nodes/interface.d.ts +2 -2
- package/dist/internal/nodes/nodesAccess.d.ts +7 -7
- package/dist/internal/nodes/nodesAccess.js +28 -16
- package/dist/internal/nodes/nodesAccess.js.map +1 -1
- package/dist/internal/nodes/nodesAccess.test.js +39 -13
- package/dist/internal/nodes/nodesAccess.test.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.d.ts +6 -6
- package/dist/internal/nodes/nodesManagement.js +9 -7
- package/dist/internal/nodes/nodesManagement.js.map +1 -1
- package/dist/internal/nodes/nodesManagement.test.js +9 -9
- package/dist/internal/nodes/nodesManagement.test.js.map +1 -1
- package/dist/internal/nodes/nodesRevisions.d.ts +4 -4
- package/dist/internal/nodes/nodesRevisions.js.map +1 -1
- package/dist/internal/photos/albums.d.ts +3 -3
- package/dist/internal/photos/albums.js.map +1 -1
- package/dist/internal/photos/apiService.d.ts +1 -1
- package/dist/internal/photos/apiService.js +3 -6
- package/dist/internal/photos/apiService.js.map +1 -1
- package/dist/internal/photos/cache.d.ts +1 -1
- package/dist/internal/photos/index.d.ts +5 -5
- package/dist/internal/photos/index.js.map +1 -1
- package/dist/internal/photos/interface.d.ts +2 -2
- package/dist/internal/photos/photosTimeline.d.ts +3 -3
- package/dist/internal/photos/photosTimeline.js +1 -2
- package/dist/internal/photos/photosTimeline.js.map +1 -1
- package/dist/internal/sdkEvents.d.ts +1 -1
- package/dist/internal/sdkEvents.js +2 -7
- package/dist/internal/sdkEvents.js.map +1 -1
- package/dist/internal/sdkEvents.test.js +8 -8
- package/dist/internal/shares/apiService.d.ts +2 -2
- package/dist/internal/shares/apiService.js +5 -3
- package/dist/internal/shares/apiService.js.map +1 -1
- package/dist/internal/shares/cache.d.ts +2 -2
- package/dist/internal/shares/cache.js +12 -6
- package/dist/internal/shares/cache.js.map +1 -1
- package/dist/internal/shares/cache.test.js.map +1 -1
- package/dist/internal/shares/cryptoCache.d.ts +2 -2
- package/dist/internal/shares/cryptoCache.test.js +8 -2
- package/dist/internal/shares/cryptoCache.test.js.map +1 -1
- package/dist/internal/shares/cryptoService.d.ts +3 -3
- package/dist/internal/shares/cryptoService.js.map +1 -1
- package/dist/internal/shares/cryptoService.test.js +42 -42
- package/dist/internal/shares/cryptoService.test.js.map +1 -1
- package/dist/internal/shares/index.d.ts +4 -4
- package/dist/internal/shares/index.js.map +1 -1
- package/dist/internal/shares/interface.d.ts +2 -2
- package/dist/internal/shares/manager.d.ts +7 -7
- package/dist/internal/shares/manager.js.map +1 -1
- package/dist/internal/shares/manager.test.js +71 -63
- package/dist/internal/shares/manager.test.js.map +1 -1
- package/dist/internal/sharing/apiService.d.ts +4 -4
- package/dist/internal/sharing/apiService.js +4 -3
- package/dist/internal/sharing/apiService.js.map +1 -1
- package/dist/internal/sharing/cache.d.ts +2 -1
- package/dist/internal/sharing/cache.js +9 -0
- package/dist/internal/sharing/cache.js.map +1 -1
- package/dist/internal/sharing/cache.test.js +33 -33
- package/dist/internal/sharing/cryptoService.d.ts +3 -3
- package/dist/internal/sharing/cryptoService.js +3 -5
- package/dist/internal/sharing/cryptoService.js.map +1 -1
- package/dist/internal/sharing/cryptoService.test.js +39 -39
- package/dist/internal/sharing/cryptoService.test.js.map +1 -1
- package/dist/internal/sharing/events.d.ts +5 -4
- package/dist/internal/sharing/events.js +28 -19
- package/dist/internal/sharing/events.js.map +1 -1
- package/dist/internal/sharing/events.test.js +101 -88
- package/dist/internal/sharing/events.test.js.map +1 -1
- package/dist/internal/sharing/index.d.ts +6 -6
- package/dist/internal/sharing/index.js.map +1 -1
- package/dist/internal/sharing/interface.d.ts +5 -4
- package/dist/internal/sharing/sharingAccess.d.ts +6 -6
- package/dist/internal/sharing/sharingAccess.js +8 -4
- package/dist/internal/sharing/sharingAccess.js.map +1 -1
- package/dist/internal/sharing/sharingAccess.test.js +45 -39
- package/dist/internal/sharing/sharingAccess.test.js.map +1 -1
- package/dist/internal/sharing/sharingManagement.d.ts +4 -4
- package/dist/internal/sharing/sharingManagement.js +5 -7
- package/dist/internal/sharing/sharingManagement.js.map +1 -1
- package/dist/internal/sharing/sharingManagement.test.js +297 -248
- package/dist/internal/sharing/sharingManagement.test.js.map +1 -1
- package/dist/internal/uids.js.map +1 -1
- package/dist/internal/upload/apiService.d.ts +3 -3
- package/dist/internal/upload/apiService.js +1 -1
- package/dist/internal/upload/apiService.js.map +1 -1
- package/dist/internal/upload/blockVerifier.d.ts +3 -3
- package/dist/internal/upload/blockVerifier.js +1 -1
- package/dist/internal/upload/blockVerifier.js.map +1 -1
- package/dist/internal/upload/chunkStreamReader.test.js +6 -6
- package/dist/internal/upload/cryptoService.d.ts +4 -4
- package/dist/internal/upload/cryptoService.js +4 -4
- package/dist/internal/upload/cryptoService.js.map +1 -1
- package/dist/internal/upload/digests.js.map +1 -1
- package/dist/internal/upload/fileUploader.d.ts +6 -6
- package/dist/internal/upload/fileUploader.js.map +1 -1
- package/dist/internal/upload/fileUploader.test.js.map +1 -1
- package/dist/internal/upload/index.d.ts +5 -5
- package/dist/internal/upload/index.js.map +1 -1
- package/dist/internal/upload/interface.d.ts +4 -3
- package/dist/internal/upload/manager.d.ts +5 -5
- package/dist/internal/upload/manager.js +15 -9
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +139 -128
- package/dist/internal/upload/manager.test.js.map +1 -1
- package/dist/internal/upload/streamUploader.d.ts +6 -6
- package/dist/internal/upload/streamUploader.js +9 -7
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.test.js +17 -12
- package/dist/internal/upload/streamUploader.test.js.map +1 -1
- package/dist/internal/upload/telemetry.d.ts +3 -3
- package/dist/internal/upload/telemetry.js +5 -3
- package/dist/internal/upload/telemetry.js.map +1 -1
- package/dist/internal/upload/telemetry.test.js +8 -8
- package/dist/internal/upload/telemetry.test.js.map +1 -1
- package/dist/protonDriveClient.d.ts +8 -8
- package/dist/protonDriveClient.js +12 -9
- package/dist/protonDriveClient.js.map +1 -1
- package/dist/protonDrivePhotosClient.js.map +1 -1
- package/dist/telemetry.js +18 -15
- package/dist/telemetry.js.map +1 -1
- package/dist/tests/logger.js.map +1 -1
- package/dist/tests/telemetry.d.ts +1 -1
- package/dist/transformers.d.ts +1 -1
- package/dist/transformers.js +5 -2
- package/dist/transformers.js.map +1 -1
- package/package.json +1 -1
- package/src/cache/interface.ts +22 -22
- package/src/cache/memoryCache.test.ts +7 -7
- package/src/cache/memoryCache.ts +4 -4
- package/src/cache/nullCache.ts +1 -1
- package/src/config.ts +5 -5
- package/src/crypto/driveCrypto.test.ts +15 -15
- package/src/crypto/driveCrypto.ts +120 -156
- package/src/crypto/hmac.ts +1 -1
- package/src/crypto/interface.ts +63 -72
- package/src/crypto/openPGPCrypto.ts +74 -94
- package/src/crypto/utils.ts +1 -1
- package/src/diagnostic/eventsGenerator.ts +2 -2
- package/src/diagnostic/httpClient.ts +6 -2
- package/src/diagnostic/index.ts +12 -10
- package/src/diagnostic/integrityVerificationStream.ts +3 -4
- package/src/diagnostic/interface.ts +81 -81
- package/src/diagnostic/sdkDiagnostic.ts +35 -24
- package/src/diagnostic/sdkDiagnosticFull.ts +16 -19
- package/src/diagnostic/telemetry.ts +4 -1
- package/src/diagnostic/zipGenerators.test.ts +1 -1
- package/src/diagnostic/zipGenerators.ts +3 -3
- package/src/errors.ts +21 -21
- package/src/index.ts +3 -3
- package/src/interface/account.ts +10 -10
- package/src/interface/author.ts +6 -6
- package/src/interface/config.ts +4 -4
- package/src/interface/devices.ts +6 -6
- package/src/interface/download.ts +12 -9
- package/src/interface/events.ts +45 -39
- package/src/interface/httpClient.ts +11 -11
- package/src/interface/index.ts +76 -19
- package/src/interface/nodes.ts +47 -49
- package/src/interface/result.ts +1 -3
- package/src/interface/sharing.ts +60 -57
- package/src/interface/telemetry.ts +74 -74
- package/src/interface/thumbnail.ts +5 -6
- package/src/interface/upload.ts +20 -12
- package/src/internal/apiService/apiService.test.ts +109 -76
- package/src/internal/apiService/apiService.ts +40 -26
- package/src/internal/apiService/coreTypes.ts +2474 -2463
- package/src/internal/apiService/driveTypes.ts +1868 -1822
- package/src/internal/apiService/errorCodes.ts +4 -4
- package/src/internal/apiService/errors.test.ts +25 -23
- package/src/internal/apiService/errors.ts +15 -9
- package/src/internal/apiService/index.ts +1 -1
- package/src/internal/apiService/transformers.ts +2 -2
- package/src/internal/asyncIteratorMap.test.ts +4 -4
- package/src/internal/asyncIteratorMap.ts +1 -1
- package/src/internal/asyncIteratorRace.test.ts +149 -0
- package/src/internal/asyncIteratorRace.ts +79 -0
- package/src/internal/batch.test.ts +50 -0
- package/src/internal/batch.ts +9 -0
- package/src/internal/batchLoading.test.ts +13 -14
- package/src/internal/batchLoading.ts +8 -8
- package/src/internal/devices/apiService.ts +58 -51
- package/src/internal/devices/cryptoService.ts +22 -17
- package/src/internal/devices/index.ts +17 -10
- package/src/internal/devices/interface.ts +21 -12
- package/src/internal/devices/manager.test.ts +40 -9
- package/src/internal/devices/manager.ts +3 -3
- package/src/internal/download/apiService.ts +66 -49
- package/src/internal/download/cryptoService.ts +34 -18
- package/src/internal/download/fileDownloader.test.ts +25 -9
- package/src/internal/download/fileDownloader.ts +36 -18
- package/src/internal/download/index.ts +19 -19
- package/src/internal/download/interface.ts +19 -20
- package/src/internal/download/queue.ts +3 -3
- package/src/internal/download/telemetry.test.ts +11 -11
- package/src/internal/download/telemetry.ts +24 -14
- package/src/internal/download/thumbnailDownloader.test.ts +11 -6
- package/src/internal/download/thumbnailDownloader.ts +43 -32
- package/src/internal/errors.ts +7 -5
- package/src/internal/events/apiService.ts +30 -17
- package/src/internal/events/coreEventManager.test.ts +18 -18
- package/src/internal/events/coreEventManager.ts +9 -6
- package/src/internal/events/eventManager.test.ts +108 -82
- package/src/internal/events/eventManager.ts +16 -5
- package/src/internal/events/index.ts +75 -47
- package/src/internal/events/interface.ts +47 -39
- package/src/internal/events/volumeEventManager.test.ts +61 -65
- package/src/internal/events/volumeEventManager.ts +18 -9
- package/src/internal/nodes/apiService.test.ts +197 -147
- package/src/internal/nodes/apiService.ts +288 -174
- package/src/internal/nodes/cache.test.ts +48 -20
- package/src/internal/nodes/cache.ts +60 -44
- package/src/internal/nodes/cryptoCache.test.ts +34 -14
- package/src/internal/nodes/cryptoCache.ts +10 -5
- package/src/internal/nodes/cryptoService.test.ts +492 -351
- package/src/internal/nodes/cryptoService.ts +170 -88
- package/src/internal/nodes/events.test.ts +38 -28
- package/src/internal/nodes/events.ts +13 -12
- package/src/internal/nodes/extendedAttributes.test.ts +28 -24
- package/src/internal/nodes/extendedAttributes.ts +20 -15
- package/src/internal/nodes/index.test.ts +133 -0
- package/src/internal/nodes/index.ts +27 -15
- package/src/internal/nodes/interface.ts +42 -29
- package/src/internal/nodes/nodesAccess.test.ts +124 -58
- package/src/internal/nodes/nodesAccess.ts +73 -49
- package/src/internal/nodes/nodesManagement.test.ts +32 -31
- package/src/internal/nodes/nodesManagement.ts +39 -32
- package/src/internal/nodes/nodesRevisions.ts +7 -7
- package/src/internal/nodes/validations.ts +2 -2
- package/src/internal/photos/albums.ts +5 -5
- package/src/internal/photos/apiService.ts +4 -7
- package/src/internal/photos/cache.ts +1 -1
- package/src/internal/photos/index.ts +8 -8
- package/src/internal/photos/interface.ts +2 -2
- package/src/internal/photos/photosTimeline.ts +4 -5
- package/src/internal/sdkEvents.test.ts +10 -10
- package/src/internal/sdkEvents.ts +5 -13
- package/src/internal/shares/apiService.ts +44 -33
- package/src/internal/shares/cache.test.ts +6 -4
- package/src/internal/shares/cache.ts +21 -12
- package/src/internal/shares/cryptoCache.test.ts +17 -11
- package/src/internal/shares/cryptoCache.ts +4 -4
- package/src/internal/shares/cryptoService.test.ts +72 -74
- package/src/internal/shares/cryptoService.ts +48 -23
- package/src/internal/shares/index.ts +23 -11
- package/src/internal/shares/interface.ts +8 -8
- package/src/internal/shares/manager.test.ts +88 -80
- package/src/internal/shares/manager.ts +19 -19
- package/src/internal/sharing/apiService.ts +282 -175
- package/src/internal/sharing/cache.test.ts +35 -35
- package/src/internal/sharing/cache.ts +11 -2
- package/src/internal/sharing/cryptoService.test.ts +58 -46
- package/src/internal/sharing/cryptoService.ts +121 -84
- package/src/internal/sharing/events.test.ts +113 -102
- package/src/internal/sharing/events.ts +42 -24
- package/src/internal/sharing/index.ts +22 -11
- package/src/internal/sharing/interface.ts +40 -40
- package/src/internal/sharing/sharingAccess.test.ts +71 -65
- package/src/internal/sharing/sharingAccess.ts +39 -21
- package/src/internal/sharing/sharingManagement.test.ts +398 -298
- package/src/internal/sharing/sharingManagement.ts +138 -65
- package/src/internal/uids.ts +1 -1
- package/src/internal/upload/apiService.ts +167 -117
- package/src/internal/upload/blockVerifier.ts +8 -6
- package/src/internal/upload/chunkStreamReader.test.ts +7 -7
- package/src/internal/upload/cryptoService.ts +42 -36
- package/src/internal/upload/digests.ts +2 -2
- package/src/internal/upload/fileUploader.test.ts +15 -3
- package/src/internal/upload/fileUploader.ts +39 -17
- package/src/internal/upload/index.ts +13 -14
- package/src/internal/upload/interface.ts +79 -78
- package/src/internal/upload/manager.test.ts +170 -156
- package/src/internal/upload/manager.ts +66 -39
- package/src/internal/upload/queue.ts +3 -3
- package/src/internal/upload/streamUploader.test.ts +40 -26
- package/src/internal/upload/streamUploader.ts +87 -69
- package/src/internal/upload/telemetry.test.ts +11 -11
- package/src/internal/upload/telemetry.ts +25 -15
- package/src/internal/wait.test.ts +1 -1
- package/src/internal/wait.ts +3 -3
- package/src/protonDriveClient.ts +121 -39
- package/src/protonDrivePhotosClient.ts +16 -10
- package/src/telemetry.ts +60 -52
- package/src/tests/logger.ts +1 -1
- package/src/tests/telemetry.ts +2 -2
- package/src/transformers.ts +29 -21
- package/src/version.ts +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { c } from
|
|
1
|
+
import { c } from 'ttag';
|
|
2
2
|
|
|
3
|
-
import { Logger, ProtonDriveTelemetry, UploadMetadata } from
|
|
4
|
-
import { ValidationError, NodeAlreadyExistsValidationError } from
|
|
5
|
-
import { ErrorCode } from
|
|
6
|
-
import { generateFileExtendedAttributes } from
|
|
7
|
-
import { UploadAPIService } from
|
|
8
|
-
import { UploadCryptoService } from
|
|
9
|
-
import { NodeRevisionDraft, NodesService, NodeCrypto } from
|
|
10
|
-
import { makeNodeUid, splitNodeUid } from
|
|
3
|
+
import { Logger, ProtonDriveTelemetry, UploadMetadata } from '../../interface';
|
|
4
|
+
import { ValidationError, NodeAlreadyExistsValidationError } from '../../errors';
|
|
5
|
+
import { ErrorCode } from '../apiService';
|
|
6
|
+
import { generateFileExtendedAttributes } from '../nodes';
|
|
7
|
+
import { UploadAPIService } from './apiService';
|
|
8
|
+
import { UploadCryptoService } from './cryptoService';
|
|
9
|
+
import { NodeRevisionDraft, NodesService, NodeCrypto } from './interface';
|
|
10
|
+
import { makeNodeUid, splitNodeUid } from '../uids';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* UploadManager is responsible for creating and deleting draft nodes
|
|
@@ -75,8 +75,8 @@ export class UploadManager {
|
|
|
75
75
|
metadata: UploadMetadata,
|
|
76
76
|
generatedNodeCrypto: NodeCrypto,
|
|
77
77
|
): Promise<{
|
|
78
|
-
nodeUid: string
|
|
79
|
-
nodeRevisionUid: string
|
|
78
|
+
nodeUid: string;
|
|
79
|
+
nodeRevisionUid: string;
|
|
80
80
|
}> {
|
|
81
81
|
try {
|
|
82
82
|
const result = await this.apiService.createDraft(parentFolderUid, {
|
|
@@ -88,7 +88,8 @@ export class UploadManager {
|
|
|
88
88
|
armoredNodePassphrase: generatedNodeCrypto.nodeKeys.encrypted.armoredPassphrase,
|
|
89
89
|
armoredNodePassphraseSignature: generatedNodeCrypto.nodeKeys.encrypted.armoredPassphraseSignature,
|
|
90
90
|
base64ContentKeyPacket: generatedNodeCrypto.contentKey.encrypted.base64ContentKeyPacket,
|
|
91
|
-
armoredContentKeyPacketSignature:
|
|
91
|
+
armoredContentKeyPacketSignature:
|
|
92
|
+
generatedNodeCrypto.contentKey.encrypted.armoredContentKeyPacketSignature,
|
|
92
93
|
signatureEmail: generatedNodeCrypto.signatureAddress.email,
|
|
93
94
|
});
|
|
94
95
|
return result;
|
|
@@ -97,30 +98,39 @@ export class UploadManager {
|
|
|
97
98
|
if (error.code === ErrorCode.ALREADY_EXISTS) {
|
|
98
99
|
this.logger.info(`Node with given name already exists`);
|
|
99
100
|
|
|
100
|
-
const typedDetails = error.details as
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
const typedDetails = error.details as
|
|
102
|
+
| {
|
|
103
|
+
ConflictLinkID: string;
|
|
104
|
+
ConflictRevisionID?: string;
|
|
105
|
+
ConflictDraftRevisionID?: string;
|
|
106
|
+
ConflictDraftClientUID?: string;
|
|
107
|
+
}
|
|
108
|
+
| undefined;
|
|
106
109
|
|
|
107
110
|
// If the client doesn't specify the client UID, it should
|
|
108
111
|
// never be considered own draft.
|
|
109
|
-
const isOwnDraftConflict =
|
|
112
|
+
const isOwnDraftConflict =
|
|
110
113
|
typedDetails?.ConflictDraftRevisionID &&
|
|
111
114
|
this.clientUid &&
|
|
112
|
-
typedDetails?.ConflictDraftClientUID === this.clientUid
|
|
113
|
-
);
|
|
115
|
+
typedDetails?.ConflictDraftClientUID === this.clientUid;
|
|
114
116
|
|
|
115
117
|
// If there is existing draft created by this client,
|
|
116
118
|
// automatically delete it and try to create a new one
|
|
117
119
|
// with the same name again.
|
|
118
|
-
if (
|
|
119
|
-
|
|
120
|
+
if (
|
|
121
|
+
typedDetails?.ConflictDraftRevisionID &&
|
|
122
|
+
(isOwnDraftConflict || metadata.overrideExistingDraftByOtherClient)
|
|
123
|
+
) {
|
|
124
|
+
const existingDraftNodeUid = makeNodeUid(
|
|
125
|
+
splitNodeUid(parentFolderUid).volumeId,
|
|
126
|
+
typedDetails.ConflictLinkID,
|
|
127
|
+
);
|
|
120
128
|
|
|
121
129
|
let deleteFailed = false;
|
|
122
130
|
try {
|
|
123
|
-
this.logger.warn(
|
|
131
|
+
this.logger.warn(
|
|
132
|
+
`Deleting existing draft node ${existingDraftNodeUid} by ${typedDetails.ConflictDraftClientUID}`,
|
|
133
|
+
);
|
|
124
134
|
await this.apiService.deleteDraft(existingDraftNodeUid);
|
|
125
135
|
} catch (deleteDraftError: unknown) {
|
|
126
136
|
// Do not throw, let throw the conflict error.
|
|
@@ -128,15 +138,25 @@ export class UploadManager {
|
|
|
128
138
|
this.logger.error('Failed to delete existing draft node', deleteDraftError);
|
|
129
139
|
}
|
|
130
140
|
if (!deleteFailed) {
|
|
131
|
-
return this.createDraftOnAPI(
|
|
141
|
+
return this.createDraftOnAPI(
|
|
142
|
+
parentFolderUid,
|
|
143
|
+
parentHashKey,
|
|
144
|
+
name,
|
|
145
|
+
metadata,
|
|
146
|
+
generatedNodeCrypto,
|
|
147
|
+
);
|
|
132
148
|
}
|
|
133
149
|
}
|
|
134
150
|
|
|
135
151
|
if (isOwnDraftConflict) {
|
|
136
|
-
this.logger.warn(
|
|
152
|
+
this.logger.warn(
|
|
153
|
+
`Existing draft conflict by another client ${typedDetails.ConflictDraftClientUID}`,
|
|
154
|
+
);
|
|
137
155
|
}
|
|
138
156
|
|
|
139
|
-
const existingNodeUid = typedDetails
|
|
157
|
+
const existingNodeUid = typedDetails
|
|
158
|
+
? makeNodeUid(splitNodeUid(parentFolderUid).volumeId, typedDetails.ConflictLinkID)
|
|
159
|
+
: undefined;
|
|
140
160
|
|
|
141
161
|
// If there is existing node, return special error
|
|
142
162
|
// that includes the available name the client can use.
|
|
@@ -223,7 +243,7 @@ export class UploadManager {
|
|
|
223
243
|
contentKeyPacketSessionKey: nodeKeys.contentKeyPacketSessionKey,
|
|
224
244
|
signatureAddress: signatureAddress,
|
|
225
245
|
},
|
|
226
|
-
}
|
|
246
|
+
};
|
|
227
247
|
}
|
|
228
248
|
|
|
229
249
|
async deleteDraftRevision(nodeRevisionUid: string): Promise<void> {
|
|
@@ -240,22 +260,29 @@ export class UploadManager {
|
|
|
240
260
|
async commitDraft(
|
|
241
261
|
nodeRevisionDraft: NodeRevisionDraft,
|
|
242
262
|
manifest: Uint8Array,
|
|
243
|
-
_metadata: UploadMetadata,
|
|
244
263
|
extendedAttributes: {
|
|
245
|
-
modificationTime?: Date
|
|
246
|
-
size?: number
|
|
247
|
-
blockSizes?: number[]
|
|
264
|
+
modificationTime?: Date;
|
|
265
|
+
size?: number;
|
|
266
|
+
blockSizes?: number[];
|
|
248
267
|
digests?: {
|
|
249
|
-
sha1?: string
|
|
250
|
-
}
|
|
268
|
+
sha1?: string;
|
|
269
|
+
};
|
|
251
270
|
},
|
|
252
271
|
): Promise<void> {
|
|
253
272
|
const generatedExtendedAttributes = generateFileExtendedAttributes(extendedAttributes);
|
|
254
|
-
const nodeCommitCrypto = await this.cryptoService.commitFile(
|
|
273
|
+
const nodeCommitCrypto = await this.cryptoService.commitFile(
|
|
274
|
+
nodeRevisionDraft.nodeKeys,
|
|
275
|
+
manifest,
|
|
276
|
+
generatedExtendedAttributes,
|
|
277
|
+
);
|
|
255
278
|
await this.apiService.commitDraftRevision(nodeRevisionDraft.nodeRevisionUid, nodeCommitCrypto);
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
279
|
+
|
|
280
|
+
// If new revision to existing node was created, invalidate the node.
|
|
281
|
+
// Otherwise notify about the new child in the parent.
|
|
282
|
+
if (nodeRevisionDraft.newNodeInfo) {
|
|
283
|
+
await this.nodesService.notifyChildCreated(nodeRevisionDraft.newNodeInfo.parentUid);
|
|
284
|
+
} else {
|
|
285
|
+
await this.nodesService.notifyNodeChanged(nodeRevisionDraft.nodeUid);
|
|
259
286
|
}
|
|
260
287
|
}
|
|
261
288
|
}
|
|
@@ -269,7 +296,7 @@ function splitExtension(filename = ''): [string, string] {
|
|
|
269
296
|
return [filename, ''];
|
|
270
297
|
}
|
|
271
298
|
return [filename.slice(0, endIdx), filename.slice(endIdx + 1)];
|
|
272
|
-
}
|
|
299
|
+
}
|
|
273
300
|
|
|
274
301
|
/**
|
|
275
302
|
* Join a filename into `name (index).extension`
|
|
@@ -2,13 +2,13 @@ import { waitForCondition } from '../wait';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* A queue that limits the number of concurrent uploads.
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* This is used to limit the number of concurrent uploads to avoid
|
|
7
7
|
* overloading the server, or get rate limited.
|
|
8
|
-
*
|
|
8
|
+
*
|
|
9
9
|
* Each file upload consumes memory and is limited by the number of
|
|
10
10
|
* concurrent block uploads for each file.
|
|
11
|
-
*
|
|
11
|
+
*
|
|
12
12
|
* This queue is straitforward and does not have any priority mechanism
|
|
13
13
|
* or other features, such as limiting total number of blocks being
|
|
14
14
|
* uploaded. That is something we want to add in the future to be
|
|
@@ -12,7 +12,12 @@ import { UploadManager } from './manager';
|
|
|
12
12
|
|
|
13
13
|
const BLOCK_ENCRYPTION_OVERHEAD = 10000;
|
|
14
14
|
|
|
15
|
-
async function mockEncryptBlock(
|
|
15
|
+
async function mockEncryptBlock(
|
|
16
|
+
verifyBlock: (block: Uint8Array) => Promise<void>,
|
|
17
|
+
_: any,
|
|
18
|
+
block: Uint8Array,
|
|
19
|
+
index: number,
|
|
20
|
+
) {
|
|
16
21
|
await verifyBlock(block);
|
|
17
22
|
return {
|
|
18
23
|
index,
|
|
@@ -25,7 +30,12 @@ async function mockEncryptBlock(verifyBlock: (block: Uint8Array) => Promise<void
|
|
|
25
30
|
};
|
|
26
31
|
}
|
|
27
32
|
|
|
28
|
-
function mockUploadBlock(
|
|
33
|
+
function mockUploadBlock(
|
|
34
|
+
_: string,
|
|
35
|
+
__: string,
|
|
36
|
+
encryptedBlock: Uint8Array,
|
|
37
|
+
onProgress: (uploadedBytes: number) => void,
|
|
38
|
+
) {
|
|
29
39
|
onProgress(encryptedBlock.length);
|
|
30
40
|
}
|
|
31
41
|
|
|
@@ -137,22 +147,19 @@ describe('StreamUploader', () => {
|
|
|
137
147
|
|
|
138
148
|
const numberOfExpectedBlocks = Math.ceil(metadata.expectedSize / FILE_CHUNK_SIZE);
|
|
139
149
|
expect(uploadManager.commitDraft).toHaveBeenCalledTimes(1);
|
|
140
|
-
expect(uploadManager.commitDraft).toHaveBeenCalledWith(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
digests: {
|
|
152
|
-
sha1: expect.anything(),
|
|
153
|
-
}
|
|
150
|
+
expect(uploadManager.commitDraft).toHaveBeenCalledWith(revisionDraft, expect.anything(), {
|
|
151
|
+
size: metadata.expectedSize,
|
|
152
|
+
blockSizes: metadata.expectedSize
|
|
153
|
+
? [
|
|
154
|
+
...Array(numberOfExpectedBlocks - 1).fill(FILE_CHUNK_SIZE),
|
|
155
|
+
metadata.expectedSize % FILE_CHUNK_SIZE,
|
|
156
|
+
]
|
|
157
|
+
: [],
|
|
158
|
+
modificationTime: undefined,
|
|
159
|
+
digests: {
|
|
160
|
+
sha1: expect.anything(),
|
|
154
161
|
},
|
|
155
|
-
);
|
|
162
|
+
});
|
|
156
163
|
expect(telemetry.uploadFinished).toHaveBeenCalledTimes(1);
|
|
157
164
|
expect(telemetry.uploadFinished).toHaveBeenCalledWith('revisionUid', metadata.expectedSize + thumbnailSize);
|
|
158
165
|
expect(telemetry.uploadFailed).not.toHaveBeenCalled();
|
|
@@ -160,7 +167,11 @@ describe('StreamUploader', () => {
|
|
|
160
167
|
expect(onFinish).toHaveBeenCalledWith(false);
|
|
161
168
|
};
|
|
162
169
|
|
|
163
|
-
const verifyFailure = async (
|
|
170
|
+
const verifyFailure = async (
|
|
171
|
+
error: string,
|
|
172
|
+
uploadedBytes: number | undefined,
|
|
173
|
+
expectedSize = metadata.expectedSize,
|
|
174
|
+
) => {
|
|
164
175
|
const promise = uploader.start(stream, thumbnails, onProgress);
|
|
165
176
|
await expect(promise).rejects.toThrow(error);
|
|
166
177
|
|
|
@@ -189,7 +200,7 @@ describe('StreamUploader', () => {
|
|
|
189
200
|
{
|
|
190
201
|
type: ThumbnailType.Type1,
|
|
191
202
|
thumbnail: new Uint8Array(1024),
|
|
192
|
-
}
|
|
203
|
+
},
|
|
193
204
|
];
|
|
194
205
|
thumbnailSize = thumbnails.reduce((acc, thumbnail) => acc + thumbnail.thumbnail.length, 0);
|
|
195
206
|
stream = new ReadableStream({
|
|
@@ -204,7 +215,7 @@ describe('StreamUploader', () => {
|
|
|
204
215
|
});
|
|
205
216
|
});
|
|
206
217
|
|
|
207
|
-
it(
|
|
218
|
+
it('should upload successfully', async () => {
|
|
208
219
|
await verifySuccess();
|
|
209
220
|
expect(apiService.requestBlockUpload).toHaveBeenCalledTimes(1);
|
|
210
221
|
expect(apiService.uploadBlock).toHaveBeenCalledTimes(4); // 3 blocks + 1 thumbnail
|
|
@@ -213,7 +224,7 @@ describe('StreamUploader', () => {
|
|
|
213
224
|
await verifyOnProgress([thumbnailSize, 4 * 1024 * 1024, 4 * 1024 * 1024, 2 * 1024 * 1024]);
|
|
214
225
|
});
|
|
215
226
|
|
|
216
|
-
it(
|
|
227
|
+
it('should upload successfully empty file without thumbnail', async () => {
|
|
217
228
|
metadata = {
|
|
218
229
|
expectedSize: 0,
|
|
219
230
|
} as UploadMetadata;
|
|
@@ -242,7 +253,7 @@ describe('StreamUploader', () => {
|
|
|
242
253
|
await verifyOnProgress([]);
|
|
243
254
|
});
|
|
244
255
|
|
|
245
|
-
it(
|
|
256
|
+
it('should upload successfully empty file with thumbnail', async () => {
|
|
246
257
|
metadata = {
|
|
247
258
|
expectedSize: 0,
|
|
248
259
|
} as UploadMetadata;
|
|
@@ -395,7 +406,7 @@ describe('StreamUploader', () => {
|
|
|
395
406
|
hash: 'blockHash',
|
|
396
407
|
armoredSignature: 'signature',
|
|
397
408
|
verificationToken: 'verificationToken',
|
|
398
|
-
}
|
|
409
|
+
},
|
|
399
410
|
],
|
|
400
411
|
},
|
|
401
412
|
);
|
|
@@ -420,9 +431,12 @@ describe('StreamUploader', () => {
|
|
|
420
431
|
});
|
|
421
432
|
|
|
422
433
|
it('should report block verification error when retry helped', async () => {
|
|
423
|
-
blockVerifier.verifyBlock = jest
|
|
424
|
-
|
|
425
|
-
|
|
434
|
+
blockVerifier.verifyBlock = jest
|
|
435
|
+
.fn()
|
|
436
|
+
.mockRejectedValueOnce(new IntegrityError('Block verification error'))
|
|
437
|
+
.mockResolvedValue({
|
|
438
|
+
verificationToken: new Uint8Array(),
|
|
439
|
+
});
|
|
426
440
|
await verifySuccess();
|
|
427
441
|
expect(telemetry.logBlockVerificationError).toHaveBeenCalledWith(true);
|
|
428
442
|
});
|
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { c } from
|
|
2
|
-
|
|
3
|
-
import { Thumbnail, Logger, ThumbnailType, UploadMetadata } from
|
|
4
|
-
import { IntegrityError } from
|
|
5
|
-
import { LoggerWithPrefix } from
|
|
6
|
-
import { APIHTTPError, HTTPErrorCode, NotFoundAPIError } from
|
|
7
|
-
import { getErrorMessage } from
|
|
8
|
-
import { mergeUint8Arrays } from
|
|
1
|
+
import { c } from 'ttag';
|
|
2
|
+
|
|
3
|
+
import { Thumbnail, Logger, ThumbnailType, UploadMetadata } from '../../interface';
|
|
4
|
+
import { IntegrityError } from '../../errors';
|
|
5
|
+
import { LoggerWithPrefix } from '../../telemetry';
|
|
6
|
+
import { APIHTTPError, HTTPErrorCode, NotFoundAPIError } from '../apiService';
|
|
7
|
+
import { getErrorMessage } from '../errors';
|
|
8
|
+
import { mergeUint8Arrays } from '../utils';
|
|
9
9
|
import { waitForCondition } from '../wait';
|
|
10
|
-
import { UploadAPIService } from
|
|
11
|
-
import { BlockVerifier } from
|
|
10
|
+
import { UploadAPIService } from './apiService';
|
|
11
|
+
import { BlockVerifier } from './blockVerifier';
|
|
12
12
|
import { UploadController } from './controller';
|
|
13
|
-
import { UploadCryptoService } from
|
|
14
|
-
import { UploadDigests } from
|
|
15
|
-
import { NodeRevisionDraft, EncryptedBlock, EncryptedThumbnail, EncryptedBlockMetadata } from
|
|
13
|
+
import { UploadCryptoService } from './cryptoService';
|
|
14
|
+
import { UploadDigests } from './digests';
|
|
15
|
+
import { NodeRevisionDraft, EncryptedBlock, EncryptedThumbnail, EncryptedBlockMetadata } from './interface';
|
|
16
16
|
import { UploadTelemetry } from './telemetry';
|
|
17
17
|
import { ChunkStreamReader } from './chunkStreamReader';
|
|
18
|
-
import { UploadManager } from
|
|
18
|
+
import { UploadManager } from './manager';
|
|
19
19
|
|
|
20
20
|
/**
|
|
21
21
|
* File chunk size in bytes representing the size of each block.
|
|
@@ -65,10 +65,13 @@ export class StreamUploader {
|
|
|
65
65
|
private encryptedBlocks = new Map<number, EncryptedBlock>();
|
|
66
66
|
private encryptionFinished = false;
|
|
67
67
|
|
|
68
|
-
private ongoingUploads = new Map<
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
private ongoingUploads = new Map<
|
|
69
|
+
string,
|
|
70
|
+
{
|
|
71
|
+
uploadPromise: Promise<void>;
|
|
72
|
+
encryptedBlock: EncryptedBlock | EncryptedThumbnail;
|
|
73
|
+
}
|
|
74
|
+
>();
|
|
72
75
|
private uploadedThumbnails: ({ type: ThumbnailType } & EncryptedBlockMetadata)[] = [];
|
|
73
76
|
private uploadedBlocks: ({ index: number } & EncryptedBlockMetadata)[] = [];
|
|
74
77
|
|
|
@@ -104,7 +107,11 @@ export class StreamUploader {
|
|
|
104
107
|
this.controller = new UploadController();
|
|
105
108
|
}
|
|
106
109
|
|
|
107
|
-
async start(
|
|
110
|
+
async start(
|
|
111
|
+
stream: ReadableStream,
|
|
112
|
+
thumbnails: Thumbnail[],
|
|
113
|
+
onProgress?: (uploadedBytes: number) => void,
|
|
114
|
+
): Promise<string> {
|
|
108
115
|
let failure = false;
|
|
109
116
|
|
|
110
117
|
// File progress is tracked for telemetry - to track at what
|
|
@@ -116,7 +123,7 @@ export class StreamUploader {
|
|
|
116
123
|
await this.encryptAndUploadBlocks(stream, thumbnails, (uploadedBytes) => {
|
|
117
124
|
fileProgress += uploadedBytes;
|
|
118
125
|
onProgress?.(uploadedBytes);
|
|
119
|
-
})
|
|
126
|
+
});
|
|
120
127
|
|
|
121
128
|
this.logger.debug(`All blocks uploaded, committing`);
|
|
122
129
|
await this.commitFile(thumbnails);
|
|
@@ -126,7 +133,12 @@ export class StreamUploader {
|
|
|
126
133
|
} catch (error: unknown) {
|
|
127
134
|
failure = true;
|
|
128
135
|
this.logger.error(`Upload failed`, error);
|
|
129
|
-
void this.telemetry.uploadFailed(
|
|
136
|
+
void this.telemetry.uploadFailed(
|
|
137
|
+
this.revisionDraft.nodeRevisionUid,
|
|
138
|
+
error,
|
|
139
|
+
fileProgress,
|
|
140
|
+
this.metadata.expectedSize,
|
|
141
|
+
);
|
|
130
142
|
throw error;
|
|
131
143
|
} finally {
|
|
132
144
|
this.logger.debug(`Upload cleanup`);
|
|
@@ -145,7 +157,11 @@ export class StreamUploader {
|
|
|
145
157
|
return this.revisionDraft.nodeRevisionUid;
|
|
146
158
|
}
|
|
147
159
|
|
|
148
|
-
private async encryptAndUploadBlocks(
|
|
160
|
+
private async encryptAndUploadBlocks(
|
|
161
|
+
stream: ReadableStream,
|
|
162
|
+
thumbnails: Thumbnail[],
|
|
163
|
+
onProgress?: (uploadedBytes: number) => void,
|
|
164
|
+
) {
|
|
149
165
|
// We await for the encryption of thumbnails to finish before
|
|
150
166
|
// starting the upload. This is because we need to request the
|
|
151
167
|
// upload tokens for the thumbnails with the first blocks.
|
|
@@ -198,15 +214,10 @@ export class StreamUploader {
|
|
|
198
214
|
const extendedAttributes = {
|
|
199
215
|
modificationTime: this.metadata.modificationTime,
|
|
200
216
|
size: this.metadata.expectedSize,
|
|
201
|
-
blockSizes: uploadedBlocks.map(block => block.originalSize),
|
|
217
|
+
blockSizes: uploadedBlocks.map((block) => block.originalSize),
|
|
202
218
|
digests: this.digests.digests(),
|
|
203
219
|
};
|
|
204
|
-
await this.uploadManager.commitDraft(
|
|
205
|
-
this.revisionDraft,
|
|
206
|
-
this.manifest,
|
|
207
|
-
this.metadata,
|
|
208
|
-
extendedAttributes,
|
|
209
|
-
);
|
|
220
|
+
await this.uploadManager.commitDraft(this.revisionDraft, this.manifest, extendedAttributes);
|
|
210
221
|
}
|
|
211
222
|
|
|
212
223
|
private async encryptThumbnails(thumbnails: Thumbnail[]) {
|
|
@@ -216,7 +227,10 @@ export class StreamUploader {
|
|
|
216
227
|
|
|
217
228
|
for (const thumbnail of thumbnails) {
|
|
218
229
|
this.logger.debug(`Encrypting thumbnail ${thumbnail.type}`);
|
|
219
|
-
const encryptedThumbnail = await this.cryptoService.encryptThumbnail(
|
|
230
|
+
const encryptedThumbnail = await this.cryptoService.encryptThumbnail(
|
|
231
|
+
this.revisionDraft.nodeKeys,
|
|
232
|
+
thumbnail,
|
|
233
|
+
);
|
|
220
234
|
this.encryptedThumbnails.set(thumbnail.type, encryptedThumbnail);
|
|
221
235
|
}
|
|
222
236
|
}
|
|
@@ -256,7 +270,9 @@ export class StreamUploader {
|
|
|
256
270
|
}
|
|
257
271
|
|
|
258
272
|
if (attempt <= MAX_BLOCK_ENCRYPTION_RETRIES) {
|
|
259
|
-
this.logger.warn(
|
|
273
|
+
this.logger.warn(
|
|
274
|
+
`Block encryption failed #${attempt}, retrying: ${getErrorMessage(error)}`,
|
|
275
|
+
);
|
|
260
276
|
continue;
|
|
261
277
|
}
|
|
262
278
|
|
|
@@ -280,18 +296,22 @@ export class StreamUploader {
|
|
|
280
296
|
this.revisionDraft.nodeRevisionUid,
|
|
281
297
|
this.revisionDraft.nodeKeys.signatureAddress.addressId,
|
|
282
298
|
{
|
|
283
|
-
contentBlocks: Array.from(
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
299
|
+
contentBlocks: Array.from(
|
|
300
|
+
this.encryptedBlocks.values().map((block) => ({
|
|
301
|
+
index: block.index,
|
|
302
|
+
encryptedSize: block.encryptedSize,
|
|
303
|
+
hash: block.hash,
|
|
304
|
+
armoredSignature: block.armoredSignature,
|
|
305
|
+
verificationToken: block.verificationToken,
|
|
306
|
+
})),
|
|
307
|
+
),
|
|
308
|
+
thumbnails: Array.from(
|
|
309
|
+
this.encryptedThumbnails.values().map((block) => ({
|
|
310
|
+
type: block.type,
|
|
311
|
+
encryptedSize: block.encryptedSize,
|
|
312
|
+
hash: block.hash,
|
|
313
|
+
})),
|
|
314
|
+
),
|
|
295
315
|
},
|
|
296
316
|
);
|
|
297
317
|
|
|
@@ -305,11 +325,7 @@ export class StreamUploader {
|
|
|
305
325
|
|
|
306
326
|
const uploadKey = `thumbnail:${thumbnailToken.type}`;
|
|
307
327
|
this.ongoingUploads.set(uploadKey, {
|
|
308
|
-
uploadPromise: this.uploadThumbnail(
|
|
309
|
-
thumbnailToken,
|
|
310
|
-
encryptedThumbnail,
|
|
311
|
-
onProgress,
|
|
312
|
-
).finally(() => {
|
|
328
|
+
uploadPromise: this.uploadThumbnail(thumbnailToken, encryptedThumbnail, onProgress).finally(() => {
|
|
313
329
|
this.ongoingUploads.delete(uploadKey);
|
|
314
330
|
|
|
315
331
|
// Help the garbage collector to clean up the memory.
|
|
@@ -329,11 +345,7 @@ export class StreamUploader {
|
|
|
329
345
|
|
|
330
346
|
const uploadKey = `block:${blockToken.index}`;
|
|
331
347
|
this.ongoingUploads.set(uploadKey, {
|
|
332
|
-
uploadPromise: this.uploadBlock(
|
|
333
|
-
blockToken,
|
|
334
|
-
encryptedBlock,
|
|
335
|
-
onProgress,
|
|
336
|
-
).finally(() => {
|
|
348
|
+
uploadPromise: this.uploadBlock(blockToken, encryptedBlock, onProgress).finally(() => {
|
|
337
349
|
this.ongoingUploads.delete(uploadKey);
|
|
338
350
|
|
|
339
351
|
// Help the garbage collector to clean up the memory.
|
|
@@ -345,11 +357,14 @@ export class StreamUploader {
|
|
|
345
357
|
}
|
|
346
358
|
|
|
347
359
|
private async uploadThumbnail(
|
|
348
|
-
uploadToken: { bareUrl: string
|
|
360
|
+
uploadToken: { bareUrl: string; token: string },
|
|
349
361
|
encryptedThumbnail: EncryptedThumbnail,
|
|
350
362
|
onProgress?: (uploadedBytes: number) => void,
|
|
351
363
|
) {
|
|
352
|
-
const logger = new LoggerWithPrefix(
|
|
364
|
+
const logger = new LoggerWithPrefix(
|
|
365
|
+
this.logger,
|
|
366
|
+
`thumbnail type ${encryptedThumbnail.type} to ${uploadToken.token}`,
|
|
367
|
+
);
|
|
353
368
|
logger.info(`Upload started`);
|
|
354
369
|
|
|
355
370
|
let blockProgress = 0;
|
|
@@ -368,13 +383,13 @@ export class StreamUploader {
|
|
|
368
383
|
onProgress?.(uploadedBytes);
|
|
369
384
|
},
|
|
370
385
|
this.abortController.signal,
|
|
371
|
-
)
|
|
386
|
+
);
|
|
372
387
|
this.uploadedThumbnails.push({
|
|
373
388
|
type: encryptedThumbnail.type,
|
|
374
389
|
hash: encryptedThumbnail.hash,
|
|
375
390
|
encryptedSize: encryptedThumbnail.encryptedSize,
|
|
376
391
|
originalSize: encryptedThumbnail.originalSize,
|
|
377
|
-
})
|
|
392
|
+
});
|
|
378
393
|
break;
|
|
379
394
|
} catch (error: unknown) {
|
|
380
395
|
if (blockProgress !== 0) {
|
|
@@ -407,7 +422,7 @@ export class StreamUploader {
|
|
|
407
422
|
}
|
|
408
423
|
|
|
409
424
|
private async uploadBlock(
|
|
410
|
-
uploadToken: { index: number
|
|
425
|
+
uploadToken: { index: number; bareUrl: string; token: string },
|
|
411
426
|
encryptedBlock: EncryptedBlock,
|
|
412
427
|
onProgress?: (uploadedBytes: number) => void,
|
|
413
428
|
) {
|
|
@@ -430,13 +445,13 @@ export class StreamUploader {
|
|
|
430
445
|
onProgress?.(uploadedBytes);
|
|
431
446
|
},
|
|
432
447
|
this.abortController.signal,
|
|
433
|
-
)
|
|
448
|
+
);
|
|
434
449
|
this.uploadedBlocks.push({
|
|
435
450
|
index: encryptedBlock.index,
|
|
436
451
|
hash: encryptedBlock.hash,
|
|
437
452
|
encryptedSize: encryptedBlock.encryptedSize,
|
|
438
453
|
originalSize: encryptedBlock.originalSize,
|
|
439
|
-
})
|
|
454
|
+
});
|
|
440
455
|
break;
|
|
441
456
|
} catch (error: unknown) {
|
|
442
457
|
if (blockProgress !== 0) {
|
|
@@ -446,20 +461,22 @@ export class StreamUploader {
|
|
|
446
461
|
|
|
447
462
|
if (
|
|
448
463
|
(error instanceof APIHTTPError && error.statusCode === HTTPErrorCode.NOT_FOUND) ||
|
|
449
|
-
|
|
464
|
+
error instanceof NotFoundAPIError
|
|
450
465
|
) {
|
|
451
466
|
logger.warn(`Token expired, fetching new token and retrying`);
|
|
452
467
|
const uploadTokens = await this.apiService.requestBlockUpload(
|
|
453
468
|
this.revisionDraft.nodeRevisionUid,
|
|
454
469
|
this.revisionDraft.nodeKeys.signatureAddress.addressId,
|
|
455
470
|
{
|
|
456
|
-
contentBlocks: [
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
471
|
+
contentBlocks: [
|
|
472
|
+
{
|
|
473
|
+
index: encryptedBlock.index,
|
|
474
|
+
encryptedSize: encryptedBlock.encryptedSize,
|
|
475
|
+
hash: encryptedBlock.hash,
|
|
476
|
+
armoredSignature: encryptedBlock.armoredSignature,
|
|
477
|
+
verificationToken: encryptedBlock.verificationToken,
|
|
478
|
+
},
|
|
479
|
+
],
|
|
463
480
|
},
|
|
464
481
|
);
|
|
465
482
|
uploadToken = uploadTokens.blockTokens[0];
|
|
@@ -498,7 +515,8 @@ export class StreamUploader {
|
|
|
498
515
|
}
|
|
499
516
|
|
|
500
517
|
private verifyIntegrity(thumbnails: Thumbnail[]) {
|
|
501
|
-
const expectedBlockCount =
|
|
518
|
+
const expectedBlockCount =
|
|
519
|
+
Math.ceil(this.metadata.expectedSize / FILE_CHUNK_SIZE) + (thumbnails ? thumbnails?.length : 0);
|
|
502
520
|
if (this.uploadedBlockCount !== expectedBlockCount) {
|
|
503
521
|
throw new IntegrityError(c('Error').t`Some file parts failed to upload`, {
|
|
504
522
|
uploadedBlockCount: this.uploadedBlockCount,
|