@protontech/drive-sdk 0.1.0 → 0.1.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/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 +1 -1
- package/dist/internal/events/eventManager.js +0 -1
- package/dist/internal/events/eventManager.js.map +1 -1
- package/dist/internal/events/eventManager.test.js +34 -25
- package/dist/internal/events/eventManager.test.js.map +1 -1
- package/dist/internal/events/index.d.ts +6 -6
- 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.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 +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 +4 -4
- package/dist/internal/sharing/events.js +0 -1
- package/dist/internal/sharing/events.js.map +1 -1
- package/dist/internal/sharing/events.test.js +39 -40
- 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 +3 -3
- package/dist/internal/upload/manager.d.ts +4 -4
- package/dist/internal/upload/manager.js +7 -5
- package/dist/internal/upload/manager.js.map +1 -1
- package/dist/internal/upload/manager.test.js +137 -123
- 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 +8 -6
- package/dist/internal/upload/streamUploader.js.map +1 -1
- package/dist/internal/upload/streamUploader.test.js +16 -11
- 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.js +4 -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 +51 -46
- package/src/internal/events/eventManager.ts +6 -5
- package/src/internal/events/index.ts +24 -14
- 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 +7 -5
- 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 +2 -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 +45 -49
- package/src/internal/sharing/events.ts +9 -6
- 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 +78 -78
- package/src/internal/upload/manager.test.ts +170 -153
- package/src/internal/upload/manager.ts +59 -35
- 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 +27 -21
- package/src/version.ts +0 -1
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
import { getMockLogger } from
|
|
2
|
-
import { PrivateKey } from
|
|
3
|
-
import { DecryptionError } from
|
|
4
|
-
import { NodeAPIService } from
|
|
5
|
-
import { NodesCache } from
|
|
6
|
-
import { NodesCryptoCache } from
|
|
7
|
-
import { NodesCryptoService } from
|
|
1
|
+
import { getMockLogger } from '../../tests/logger';
|
|
2
|
+
import { PrivateKey } from '../../crypto';
|
|
3
|
+
import { DecryptionError } from '../../errors';
|
|
4
|
+
import { NodeAPIService } from './apiService';
|
|
5
|
+
import { NodesCache } from './cache';
|
|
6
|
+
import { NodesCryptoCache } from './cryptoCache';
|
|
7
|
+
import { NodesCryptoService } from './cryptoService';
|
|
8
8
|
import { NodesAccess } from './nodesAccess';
|
|
9
|
-
import { SharesService, DecryptedNode, DecryptedUnparsedNode, EncryptedNode, DecryptedNodeKeys } from
|
|
10
|
-
import { NodeType } from
|
|
9
|
+
import { SharesService, DecryptedNode, DecryptedUnparsedNode, EncryptedNode, DecryptedNodeKeys } from './interface';
|
|
10
|
+
import { NodeType } from '../../interface';
|
|
11
11
|
|
|
12
12
|
describe('nodesAccess', () => {
|
|
13
13
|
let apiService: NodeAPIService;
|
|
@@ -22,10 +22,10 @@ describe('nodesAccess', () => {
|
|
|
22
22
|
apiService = {
|
|
23
23
|
getNode: jest.fn(),
|
|
24
24
|
iterateNodes: jest.fn().mockImplementation(async function* (uids: string[]) {
|
|
25
|
-
yield* uids.map((uid => ({ uid, parentUid: 'volumeId~parentNodeId' } as EncryptedNode)
|
|
25
|
+
yield* uids.map((uid) => ({ uid, parentUid: 'volumeId~parentNodeId' }) as EncryptedNode);
|
|
26
26
|
}),
|
|
27
27
|
iterateChildrenNodeUids: jest.fn(),
|
|
28
|
-
}
|
|
28
|
+
};
|
|
29
29
|
// @ts-expect-error No need to implement all methods for mocking
|
|
30
30
|
cache = {
|
|
31
31
|
getNode: jest.fn(),
|
|
@@ -34,16 +34,16 @@ describe('nodesAccess', () => {
|
|
|
34
34
|
isFolderChildrenLoaded: jest.fn().mockResolvedValue(false),
|
|
35
35
|
setFolderChildrenLoaded: jest.fn(),
|
|
36
36
|
removeNodes: jest.fn(),
|
|
37
|
-
}
|
|
37
|
+
};
|
|
38
38
|
// @ts-expect-error No need to implement all methods for mocking
|
|
39
39
|
cryptoCache = {
|
|
40
40
|
getNodeKeys: jest.fn(),
|
|
41
41
|
setNodeKeys: jest.fn(),
|
|
42
|
-
}
|
|
42
|
+
};
|
|
43
43
|
// @ts-expect-error No need to implement all methods for mocking
|
|
44
44
|
cryptoService = {
|
|
45
45
|
decryptNode: jest.fn(),
|
|
46
|
-
}
|
|
46
|
+
};
|
|
47
47
|
// @ts-expect-error No need to implement all methods for mocking
|
|
48
48
|
shareService = {
|
|
49
49
|
getMyFilesIDs: jest.fn().mockResolvedValue({ volumeId: 'volumeId' }),
|
|
@@ -65,21 +65,27 @@ describe('nodesAccess', () => {
|
|
|
65
65
|
|
|
66
66
|
it('should get node from API when cache is stale', async () => {
|
|
67
67
|
const encryptedNode = { uid: 'volumeId~nodeId', parentUid: 'volumeId~parentNodeid' } as EncryptedNode;
|
|
68
|
-
const decryptedUnparsedNode = {
|
|
68
|
+
const decryptedUnparsedNode = {
|
|
69
|
+
uid: 'volumeId~nodeId',
|
|
70
|
+
parentUid: 'volumeId~parentNodeid',
|
|
71
|
+
name: { ok: true, value: 'name' },
|
|
72
|
+
} as DecryptedUnparsedNode;
|
|
69
73
|
const decryptedNode = {
|
|
70
74
|
...decryptedUnparsedNode,
|
|
71
75
|
name: { ok: true, value: 'name' },
|
|
72
76
|
isStale: false,
|
|
73
77
|
activeRevision: undefined,
|
|
74
78
|
folder: undefined,
|
|
75
|
-
treeEventScopeId:
|
|
79
|
+
treeEventScopeId: 'volumeId',
|
|
76
80
|
} as DecryptedNode;
|
|
77
81
|
const decryptedKeys = { key: 'key' } as any as DecryptedNodeKeys;
|
|
78
82
|
|
|
79
83
|
cache.getNode = jest.fn(() => Promise.resolve({ uid: 'volumeId~nodeId', isStale: true } as DecryptedNode));
|
|
80
84
|
apiService.getNode = jest.fn(() => Promise.resolve(encryptedNode));
|
|
81
85
|
cryptoCache.getNodeKeys = jest.fn(() => Promise.resolve({ key: 'parentKey' } as any as DecryptedNodeKeys));
|
|
82
|
-
cryptoService.decryptNode = jest.fn(() =>
|
|
86
|
+
cryptoService.decryptNode = jest.fn(() =>
|
|
87
|
+
Promise.resolve({ node: decryptedUnparsedNode, keys: decryptedKeys }),
|
|
88
|
+
);
|
|
83
89
|
|
|
84
90
|
const result = await access.getNode('volumeId~nodeId');
|
|
85
91
|
expect(result).toEqual(decryptedNode);
|
|
@@ -92,7 +98,11 @@ describe('nodesAccess', () => {
|
|
|
92
98
|
|
|
93
99
|
it('should get node from API missing cache', async () => {
|
|
94
100
|
const encryptedNode = { uid: 'volumeId~nodeId', parentUid: 'volumeId~parentNodeid' } as EncryptedNode;
|
|
95
|
-
const decryptedUnparsedNode = {
|
|
101
|
+
const decryptedUnparsedNode = {
|
|
102
|
+
uid: 'volumeId~nodeId',
|
|
103
|
+
parentUid: 'volumeId~parentNodeid',
|
|
104
|
+
name: { ok: true, value: 'name' },
|
|
105
|
+
} as DecryptedUnparsedNode;
|
|
96
106
|
const decryptedNode = {
|
|
97
107
|
...decryptedUnparsedNode,
|
|
98
108
|
name: { ok: true, value: 'name' },
|
|
@@ -106,7 +116,9 @@ describe('nodesAccess', () => {
|
|
|
106
116
|
cache.getNode = jest.fn(() => Promise.reject(new Error('Entity not found')));
|
|
107
117
|
apiService.getNode = jest.fn(() => Promise.resolve(encryptedNode));
|
|
108
118
|
cryptoCache.getNodeKeys = jest.fn(() => Promise.resolve({ key: 'parentKey' } as any as DecryptedNodeKeys));
|
|
109
|
-
cryptoService.decryptNode = jest.fn(() =>
|
|
119
|
+
cryptoService.decryptNode = jest.fn(() =>
|
|
120
|
+
Promise.resolve({ node: decryptedUnparsedNode, keys: decryptedKeys }),
|
|
121
|
+
);
|
|
110
122
|
|
|
111
123
|
const result = await access.getNode('volumeId~nodeId');
|
|
112
124
|
expect(result).toEqual(decryptedNode);
|
|
@@ -119,7 +131,11 @@ describe('nodesAccess', () => {
|
|
|
119
131
|
|
|
120
132
|
it('should validate node name', async () => {
|
|
121
133
|
const encryptedNode = { uid: 'volumeId~nodeId', parentUid: 'volumeId~parentNodeid' } as EncryptedNode;
|
|
122
|
-
const decryptedUnparsedNode = {
|
|
134
|
+
const decryptedUnparsedNode = {
|
|
135
|
+
uid: 'volumeId~nodeId',
|
|
136
|
+
parentUid: 'volumeId~parentNodeid',
|
|
137
|
+
name: { ok: true, value: 'foo/bar' },
|
|
138
|
+
} as DecryptedUnparsedNode;
|
|
123
139
|
const decryptedNode = {
|
|
124
140
|
...decryptedUnparsedNode,
|
|
125
141
|
name: { ok: false, error: { name: 'foo/bar', error: "Name must not contain the character '/'" } },
|
|
@@ -130,7 +146,9 @@ describe('nodesAccess', () => {
|
|
|
130
146
|
cache.getNode = jest.fn(() => Promise.reject(new Error('Entity not found')));
|
|
131
147
|
apiService.getNode = jest.fn(() => Promise.resolve(encryptedNode));
|
|
132
148
|
cryptoCache.getNodeKeys = jest.fn(() => Promise.resolve({ key: 'parentKey' } as any as DecryptedNodeKeys));
|
|
133
|
-
cryptoService.decryptNode = jest.fn(() =>
|
|
149
|
+
cryptoService.decryptNode = jest.fn(() =>
|
|
150
|
+
Promise.resolve({ node: decryptedUnparsedNode, keys: decryptedKeys }),
|
|
151
|
+
);
|
|
134
152
|
|
|
135
153
|
const result = await access.getNode('volumeId~nodeId');
|
|
136
154
|
expect(result).toMatchObject(decryptedNode);
|
|
@@ -139,11 +157,19 @@ describe('nodesAccess', () => {
|
|
|
139
157
|
|
|
140
158
|
describe('iterate methods', () => {
|
|
141
159
|
beforeEach(() => {
|
|
142
|
-
cryptoCache.getNodeKeys = jest
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
160
|
+
cryptoCache.getNodeKeys = jest
|
|
161
|
+
.fn()
|
|
162
|
+
.mockImplementation((uid: string) => Promise.resolve({ key: 'key' } as any as DecryptedNodeKeys));
|
|
163
|
+
cryptoService.decryptNode = jest.fn().mockImplementation((encryptedNode: EncryptedNode) =>
|
|
164
|
+
Promise.resolve({
|
|
165
|
+
node: {
|
|
166
|
+
uid: encryptedNode.uid,
|
|
167
|
+
isStale: false,
|
|
168
|
+
name: { ok: true, value: 'name' },
|
|
169
|
+
} as DecryptedNode,
|
|
170
|
+
keys: { key: 'key' } as any as DecryptedNodeKeys,
|
|
171
|
+
}),
|
|
172
|
+
);
|
|
147
173
|
});
|
|
148
174
|
|
|
149
175
|
describe('iterateChildren', () => {
|
|
@@ -222,7 +248,11 @@ describe('nodesAccess', () => {
|
|
|
222
248
|
const result = await Array.fromAsync(access.iterateFolderChildren('volumeId~parentNodeid'));
|
|
223
249
|
expect(result).toMatchObject([node1, node2, node3, node4]);
|
|
224
250
|
expect(apiService.iterateChildrenNodeUids).toHaveBeenCalledWith('volumeId~parentNodeid', undefined);
|
|
225
|
-
expect(apiService.iterateNodes).toHaveBeenCalledWith(
|
|
251
|
+
expect(apiService.iterateNodes).toHaveBeenCalledWith(
|
|
252
|
+
['volumeId~node1', 'volumeId~node2', 'volumeId~node3', 'volumeId~node4'],
|
|
253
|
+
'volumeId',
|
|
254
|
+
undefined,
|
|
255
|
+
);
|
|
226
256
|
expect(cryptoService.decryptNode).toHaveBeenCalledTimes(4);
|
|
227
257
|
expect(cache.setNode).toHaveBeenCalledTimes(4);
|
|
228
258
|
expect(cryptoCache.setNodeKeys).toHaveBeenCalledTimes(4);
|
|
@@ -243,7 +273,7 @@ describe('nodesAccess', () => {
|
|
|
243
273
|
});
|
|
244
274
|
apiService.iterateNodes = jest.fn().mockImplementation(async function* (uids: string[]) {
|
|
245
275
|
// Skip first node - make it missing.
|
|
246
|
-
yield* uids.slice(1).map((uid) => ({ uid, parentUid: parentNode.uid } as EncryptedNode)
|
|
276
|
+
yield* uids.slice(1).map((uid) => ({ uid, parentUid: parentNode.uid }) as EncryptedNode);
|
|
247
277
|
});
|
|
248
278
|
|
|
249
279
|
const result = await Array.fromAsync(access.iterateFolderChildren('volumeId~parentNodeid'));
|
|
@@ -268,7 +298,11 @@ describe('nodesAccess', () => {
|
|
|
268
298
|
throw new DecryptionError('Decryption failed');
|
|
269
299
|
}
|
|
270
300
|
return Promise.resolve({
|
|
271
|
-
node: {
|
|
301
|
+
node: {
|
|
302
|
+
uid: encryptedNode.uid,
|
|
303
|
+
isStale: false,
|
|
304
|
+
name: { ok: true, value: 'name' },
|
|
305
|
+
} as DecryptedNode,
|
|
272
306
|
keys: { key: 'key' } as any as DecryptedNodeKeys,
|
|
273
307
|
});
|
|
274
308
|
});
|
|
@@ -283,11 +317,9 @@ describe('nodesAccess', () => {
|
|
|
283
317
|
try {
|
|
284
318
|
await node3;
|
|
285
319
|
} catch (error: any) {
|
|
286
|
-
expect(error.cause).toEqual([
|
|
287
|
-
new DecryptionError('Decryption failed'),
|
|
288
|
-
]);
|
|
320
|
+
expect(error.cause).toEqual([new DecryptionError('Decryption failed')]);
|
|
289
321
|
}
|
|
290
|
-
})
|
|
322
|
+
});
|
|
291
323
|
});
|
|
292
324
|
|
|
293
325
|
describe('iterateTrashedNodes', () => {
|
|
@@ -324,7 +356,11 @@ describe('nodesAccess', () => {
|
|
|
324
356
|
const result = await Array.fromAsync(access.iterateTrashedNodes());
|
|
325
357
|
expect(result).toMatchObject([node1, node2, node3, node4]);
|
|
326
358
|
expect(apiService.iterateTrashedNodeUids).toHaveBeenCalledWith(volumeId, undefined);
|
|
327
|
-
expect(apiService.iterateNodes).toHaveBeenCalledWith(
|
|
359
|
+
expect(apiService.iterateNodes).toHaveBeenCalledWith(
|
|
360
|
+
['volumeId~node1', 'volumeId~node2', 'volumeId~node3', 'volumeId~node4'],
|
|
361
|
+
volumeId,
|
|
362
|
+
undefined,
|
|
363
|
+
);
|
|
328
364
|
expect(cryptoService.decryptNode).toHaveBeenCalledTimes(4);
|
|
329
365
|
expect(cache.setNode).toHaveBeenCalledTimes(4);
|
|
330
366
|
expect(cryptoCache.setNodeKeys).toHaveBeenCalledTimes(4);
|
|
@@ -336,7 +372,7 @@ describe('nodesAccess', () => {
|
|
|
336
372
|
});
|
|
337
373
|
apiService.iterateNodes = jest.fn().mockImplementation(async function* (uids: string[]) {
|
|
338
374
|
// Skip first node - make it missing.
|
|
339
|
-
yield* uids.slice(1).map((uid) => ({ uid, parentUid: 'volumeId~parentNodeid' } as EncryptedNode)
|
|
375
|
+
yield* uids.slice(1).map((uid) => ({ uid, parentUid: 'volumeId~parentNodeid' }) as EncryptedNode);
|
|
340
376
|
});
|
|
341
377
|
|
|
342
378
|
const result = await Array.fromAsync(access.iterateTrashedNodes());
|
|
@@ -359,7 +395,9 @@ describe('nodesAccess', () => {
|
|
|
359
395
|
yield { ok: true, node: node4 };
|
|
360
396
|
});
|
|
361
397
|
|
|
362
|
-
const result = await Array.fromAsync(
|
|
398
|
+
const result = await Array.fromAsync(
|
|
399
|
+
access.iterateNodes(['volumeId~node1', 'volumeId~node2', 'volumeId~node3', 'volumeId~node4']),
|
|
400
|
+
);
|
|
363
401
|
expect(result).toMatchObject([node1, node2, node3, node4]);
|
|
364
402
|
expect(apiService.iterateNodes).not.toHaveBeenCalled();
|
|
365
403
|
});
|
|
@@ -372,9 +410,15 @@ describe('nodesAccess', () => {
|
|
|
372
410
|
yield { ok: true, node: node4 };
|
|
373
411
|
});
|
|
374
412
|
|
|
375
|
-
const result = await Array.fromAsync(
|
|
413
|
+
const result = await Array.fromAsync(
|
|
414
|
+
access.iterateNodes(['volumeId~node1', 'volumeId~node2', 'volumeId~node3', 'volumeId~node4']),
|
|
415
|
+
);
|
|
376
416
|
expect(result).toMatchObject([node1, node4, node2, node3]);
|
|
377
|
-
expect(apiService.iterateNodes).toHaveBeenCalledWith(
|
|
417
|
+
expect(apiService.iterateNodes).toHaveBeenCalledWith(
|
|
418
|
+
['volumeId~node2', 'volumeId~node3'],
|
|
419
|
+
'volumeId',
|
|
420
|
+
undefined,
|
|
421
|
+
);
|
|
378
422
|
});
|
|
379
423
|
|
|
380
424
|
it('should remove from cache if missing on API and return back to caller', async () => {
|
|
@@ -385,11 +429,13 @@ describe('nodesAccess', () => {
|
|
|
385
429
|
});
|
|
386
430
|
apiService.iterateNodes = jest.fn().mockImplementation(async function* (uids: string[]) {
|
|
387
431
|
// Skip first node - make it missing.
|
|
388
|
-
yield* uids.slice(1).map((uid) => ({ uid, parentUid: 'volumeId~parentNodeid' } as EncryptedNode)
|
|
432
|
+
yield* uids.slice(1).map((uid) => ({ uid, parentUid: 'volumeId~parentNodeid' }) as EncryptedNode);
|
|
389
433
|
});
|
|
390
434
|
|
|
391
|
-
const result = await Array.fromAsync(
|
|
392
|
-
|
|
435
|
+
const result = await Array.fromAsync(
|
|
436
|
+
access.iterateNodes(['volumeId~node1', 'volumeId~node2', 'volumeId~node3']),
|
|
437
|
+
);
|
|
438
|
+
expect(result).toMatchObject([node2, node3, { missingUid: 'volumeId~node1' }]);
|
|
393
439
|
expect(cache.removeNodes).toHaveBeenCalledWith(['volumeId~node1']);
|
|
394
440
|
});
|
|
395
441
|
|
|
@@ -407,10 +453,10 @@ describe('nodesAccess', () => {
|
|
|
407
453
|
yield* uids.map((uid) => {
|
|
408
454
|
const parentUid = uid.replace('node', 'parentOfNode');
|
|
409
455
|
return {
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
} as EncryptedNode
|
|
456
|
+
uid,
|
|
457
|
+
parentUid,
|
|
458
|
+
encryptedCrypto,
|
|
459
|
+
} as EncryptedNode;
|
|
414
460
|
});
|
|
415
461
|
});
|
|
416
462
|
const decryptionError = new DecryptionError('Parent cannot be decrypted');
|
|
@@ -419,19 +465,27 @@ describe('nodesAccess', () => {
|
|
|
419
465
|
throw decryptionError;
|
|
420
466
|
}
|
|
421
467
|
return {
|
|
422
|
-
key: {_idx: 32132},
|
|
468
|
+
key: { _idx: 32132 },
|
|
423
469
|
} as any;
|
|
424
|
-
}
|
|
470
|
+
});
|
|
425
471
|
|
|
426
|
-
const result = await Array.fromAsync(
|
|
472
|
+
const result = await Array.fromAsync(
|
|
473
|
+
access.iterateNodes(['volumeId~node1', 'volumeId~node2', 'volumeId~node3']),
|
|
474
|
+
);
|
|
427
475
|
expect(result).toEqual([
|
|
428
476
|
{
|
|
429
477
|
...node1,
|
|
430
478
|
encryptedCrypto,
|
|
431
479
|
parentUid: 'volumeId~parentOfNode1',
|
|
432
480
|
name: { ok: false, error: decryptionError },
|
|
433
|
-
keyAuthor: {
|
|
434
|
-
|
|
481
|
+
keyAuthor: {
|
|
482
|
+
ok: false,
|
|
483
|
+
error: { claimedAuthor: 'signatureEmail', error: decryptionError.message },
|
|
484
|
+
},
|
|
485
|
+
nameAuthor: {
|
|
486
|
+
ok: false,
|
|
487
|
+
error: { claimedAuthor: 'nameSignatureEmail', error: decryptionError.message },
|
|
488
|
+
},
|
|
435
489
|
errors: [decryptionError],
|
|
436
490
|
},
|
|
437
491
|
{
|
|
@@ -530,30 +584,42 @@ describe('nodesAccess', () => {
|
|
|
530
584
|
const nodeUid = 'volumeId~nodeId';
|
|
531
585
|
|
|
532
586
|
it('should return node URL of document', async () => {
|
|
533
|
-
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
587
|
+
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
588
|
+
Promise.resolve({ mediaType: 'application/vnd.proton.doc' } as any as DecryptedNode),
|
|
589
|
+
);
|
|
534
590
|
|
|
535
591
|
const result = await access.getNodeUrl(nodeUid);
|
|
536
592
|
expect(result).toBe('https://docs.proton.me/doc?type=doc&mode=open&volumeId=volumeId&linkId=nodeId');
|
|
537
593
|
});
|
|
538
594
|
|
|
539
595
|
it('should return node URL of sheet', async () => {
|
|
540
|
-
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
596
|
+
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
597
|
+
Promise.resolve({ mediaType: 'application/vnd.proton.sheet' } as any as DecryptedNode),
|
|
598
|
+
);
|
|
541
599
|
|
|
542
600
|
const result = await access.getNodeUrl(nodeUid);
|
|
543
601
|
expect(result).toBe('https://docs.proton.me/doc?type=sheet&mode=open&volumeId=volumeId&linkId=nodeId');
|
|
544
602
|
});
|
|
545
603
|
|
|
546
604
|
it('should return node URL of image', async () => {
|
|
547
|
-
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
548
|
-
|
|
605
|
+
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
606
|
+
Promise.resolve({ type: NodeType.File } as any as DecryptedNode),
|
|
607
|
+
);
|
|
608
|
+
jest.spyOn(access as any, 'getRootNode').mockReturnValue(
|
|
609
|
+
Promise.resolve({ shareId: 'shareId', type: NodeType.Folder } as any as DecryptedNode),
|
|
610
|
+
);
|
|
549
611
|
|
|
550
612
|
const result = await access.getNodeUrl(nodeUid);
|
|
551
613
|
expect(result).toBe('https://drive.proton.me/shareId/file/nodeId');
|
|
552
614
|
});
|
|
553
615
|
|
|
554
616
|
it('should return node URL of folder', async () => {
|
|
555
|
-
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
556
|
-
|
|
617
|
+
jest.spyOn(access, 'getNode').mockReturnValue(
|
|
618
|
+
Promise.resolve({ type: NodeType.Folder } as any as DecryptedNode),
|
|
619
|
+
);
|
|
620
|
+
jest.spyOn(access as any, 'getRootNode').mockReturnValue(
|
|
621
|
+
Promise.resolve({ shareId: 'shareId', type: NodeType.Folder } as any as DecryptedNode),
|
|
622
|
+
);
|
|
557
623
|
|
|
558
624
|
const result = await access.getNodeUrl(nodeUid);
|
|
559
625
|
expect(result).toBe('https://drive.proton.me/shareId/folder/nodeId');
|
|
@@ -567,7 +633,7 @@ describe('nodesAccess', () => {
|
|
|
567
633
|
cache.setNode = jest.fn();
|
|
568
634
|
await access.notifyNodeChanged(node.uid);
|
|
569
635
|
expect(cache.getNode).toHaveBeenCalledWith(node.uid);
|
|
570
|
-
expect(cache.setNode).toHaveBeenCalledWith({...node, isStale: true});
|
|
636
|
+
expect(cache.setNode).toHaveBeenCalledWith({ ...node, isStale: true });
|
|
571
637
|
});
|
|
572
638
|
it('should update parent if needed', async () => {
|
|
573
639
|
const node = { uid: 'volumeId~nodeId', parentUid: 'v1~pn1', isStale: false } as DecryptedNode;
|
|
@@ -575,7 +641,7 @@ describe('nodesAccess', () => {
|
|
|
575
641
|
cache.setNode = jest.fn();
|
|
576
642
|
await access.notifyNodeChanged(node.uid, 'v1~pn2');
|
|
577
643
|
expect(cache.getNode).toHaveBeenCalledWith(node.uid);
|
|
578
|
-
expect(cache.setNode).toHaveBeenCalledWith({...node, parentUid: 'v1~pn2', isStale: true});
|
|
644
|
+
expect(cache.setNode).toHaveBeenCalledWith({ ...node, parentUid: 'v1~pn2', isStale: true });
|
|
579
645
|
});
|
|
580
646
|
});
|
|
581
647
|
|
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { c } from 'ttag';
|
|
2
2
|
|
|
3
|
-
import { PrivateKey, SessionKey } from
|
|
4
|
-
import { InvalidNameError, Logger, MissingNode, NodeType, Result, resultError, resultOk } from
|
|
5
|
-
import { DecryptionError, ProtonDriveError } from
|
|
3
|
+
import { PrivateKey, SessionKey } from '../../crypto';
|
|
4
|
+
import { InvalidNameError, Logger, MissingNode, NodeType, Result, resultError, resultOk } from '../../interface';
|
|
5
|
+
import { DecryptionError, ProtonDriveError } from '../../errors';
|
|
6
6
|
import { asyncIteratorMap } from '../asyncIteratorMap';
|
|
7
7
|
import { getErrorMessage } from '../errors';
|
|
8
|
-
import { BatchLoading } from
|
|
9
|
-
import { makeNodeUid, splitNodeUid } from
|
|
10
|
-
import { NodeAPIService } from
|
|
11
|
-
import { NodesCache } from
|
|
12
|
-
import { NodesCryptoCache } from
|
|
13
|
-
import { NodesCryptoService } from
|
|
14
|
-
import { parseFileExtendedAttributes, parseFolderExtendedAttributes } from
|
|
15
|
-
import { SharesService, EncryptedNode, DecryptedUnparsedNode, DecryptedNode, DecryptedNodeKeys } from
|
|
16
|
-
import { validateNodeName } from
|
|
8
|
+
import { BatchLoading } from '../batchLoading';
|
|
9
|
+
import { makeNodeUid, splitNodeUid } from '../uids';
|
|
10
|
+
import { NodeAPIService } from './apiService';
|
|
11
|
+
import { NodesCache } from './cache';
|
|
12
|
+
import { NodesCryptoCache } from './cryptoCache';
|
|
13
|
+
import { NodesCryptoService } from './cryptoService';
|
|
14
|
+
import { parseFileExtendedAttributes, parseFolderExtendedAttributes } from './extendedAttributes';
|
|
15
|
+
import { SharesService, EncryptedNode, DecryptedUnparsedNode, DecryptedNode, DecryptedNodeKeys } from './interface';
|
|
16
|
+
import { validateNodeName } from './validations';
|
|
17
17
|
import { isProtonDocument, isProtonSheet } from './mediaTypes';
|
|
18
18
|
|
|
19
19
|
// This is the number of nodes that are loaded in parallel.
|
|
@@ -59,7 +59,7 @@ export class NodesAccess {
|
|
|
59
59
|
let cachedNode;
|
|
60
60
|
try {
|
|
61
61
|
cachedNode = await this.cache.getNode(nodeUid);
|
|
62
|
-
} catch {
|
|
62
|
+
} catch {}
|
|
63
63
|
|
|
64
64
|
if (cachedNode && !cachedNode.isStale) {
|
|
65
65
|
return cachedNode;
|
|
@@ -75,7 +75,10 @@ export class NodesAccess {
|
|
|
75
75
|
// Ensure the parent is loaded and up-to-date.
|
|
76
76
|
const parentNode = await this.getNode(parentNodeUid);
|
|
77
77
|
|
|
78
|
-
const batchLoading = new BatchLoading<string, DecryptedNode>({
|
|
78
|
+
const batchLoading = new BatchLoading<string, DecryptedNode>({
|
|
79
|
+
iterateItems: (nodeUids) => this.loadNodes(nodeUids, signal),
|
|
80
|
+
batchSize: BATCH_LOADING_SIZE,
|
|
81
|
+
});
|
|
79
82
|
|
|
80
83
|
const areChildrenCached = await this.cache.isFolderChildrenLoaded(parentNodeUid);
|
|
81
84
|
if (areChildrenCached) {
|
|
@@ -95,7 +98,7 @@ export class NodesAccess {
|
|
|
95
98
|
let node;
|
|
96
99
|
try {
|
|
97
100
|
node = await this.cache.getNode(nodeUid);
|
|
98
|
-
} catch {
|
|
101
|
+
} catch {}
|
|
99
102
|
|
|
100
103
|
if (node && !node.isStale) {
|
|
101
104
|
yield node;
|
|
@@ -111,12 +114,15 @@ export class NodesAccess {
|
|
|
111
114
|
// Improvement requested: keep status of loaded trash and leverage cache.
|
|
112
115
|
async *iterateTrashedNodes(signal?: AbortSignal): AsyncGenerator<DecryptedNode> {
|
|
113
116
|
const { volumeId } = await this.shareService.getMyFilesIDs();
|
|
114
|
-
const batchLoading = new BatchLoading<string, DecryptedNode>({
|
|
117
|
+
const batchLoading = new BatchLoading<string, DecryptedNode>({
|
|
118
|
+
iterateItems: (nodeUids) => this.loadNodes(nodeUids, signal),
|
|
119
|
+
batchSize: BATCH_LOADING_SIZE,
|
|
120
|
+
});
|
|
115
121
|
for await (const nodeUid of this.apiService.iterateTrashedNodeUids(volumeId, signal)) {
|
|
116
122
|
let node;
|
|
117
123
|
try {
|
|
118
124
|
node = await this.cache.getNode(nodeUid);
|
|
119
|
-
} catch {
|
|
125
|
+
} catch {}
|
|
120
126
|
|
|
121
127
|
if (node && !node.isStale) {
|
|
122
128
|
yield node;
|
|
@@ -129,7 +135,10 @@ export class NodesAccess {
|
|
|
129
135
|
}
|
|
130
136
|
|
|
131
137
|
async *iterateNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<DecryptedNode | MissingNode> {
|
|
132
|
-
const batchLoading = new BatchLoading<string, DecryptedNode | MissingNode>({
|
|
138
|
+
const batchLoading = new BatchLoading<string, DecryptedNode | MissingNode>({
|
|
139
|
+
iterateItems: (nodeUids) => this.loadNodesWithMissingReport(nodeUids, signal),
|
|
140
|
+
batchSize: BATCH_LOADING_SIZE,
|
|
141
|
+
});
|
|
133
142
|
for await (const result of this.cache.iterateNodes(nodeUids)) {
|
|
134
143
|
if (result.ok && !result.node.isStale) {
|
|
135
144
|
yield result.node;
|
|
@@ -176,13 +185,13 @@ export class NodesAccess {
|
|
|
176
185
|
await this.cache.removeNodes([nodeUid]);
|
|
177
186
|
}
|
|
178
187
|
|
|
179
|
-
private async loadNode(nodeUid: string): Promise<{ node: DecryptedNode
|
|
188
|
+
private async loadNode(nodeUid: string): Promise<{ node: DecryptedNode; keys?: DecryptedNodeKeys }> {
|
|
180
189
|
const { volumeId: ownVolumeId } = await this.shareService.getMyFilesIDs();
|
|
181
190
|
const encryptedNode = await this.apiService.getNode(nodeUid, ownVolumeId);
|
|
182
191
|
return this.decryptNode(encryptedNode);
|
|
183
192
|
}
|
|
184
193
|
|
|
185
|
-
private async*
|
|
194
|
+
private async *loadNodes(nodeUids: string[], signal?: AbortSignal): AsyncGenerator<DecryptedNode> {
|
|
186
195
|
for await (const result of this.loadNodesWithMissingReport(nodeUids, signal)) {
|
|
187
196
|
if ('missingUid' in result) {
|
|
188
197
|
continue;
|
|
@@ -191,7 +200,10 @@ export class NodesAccess {
|
|
|
191
200
|
}
|
|
192
201
|
}
|
|
193
202
|
|
|
194
|
-
private async*
|
|
203
|
+
private async *loadNodesWithMissingReport(
|
|
204
|
+
nodeUids: string[],
|
|
205
|
+
signal?: AbortSignal,
|
|
206
|
+
): AsyncGenerator<DecryptedNode | MissingNode> {
|
|
195
207
|
const returnedNodeUids: string[] = [];
|
|
196
208
|
const errors = [];
|
|
197
209
|
|
|
@@ -207,7 +219,11 @@ export class NodesAccess {
|
|
|
207
219
|
return resultError(error);
|
|
208
220
|
}
|
|
209
221
|
};
|
|
210
|
-
const decryptedNodesIterator = asyncIteratorMap(
|
|
222
|
+
const decryptedNodesIterator = asyncIteratorMap(
|
|
223
|
+
encryptedNodesIterator,
|
|
224
|
+
decryptNodeMapper,
|
|
225
|
+
DECRYPTION_CONCURRENCY,
|
|
226
|
+
);
|
|
211
227
|
for await (const node of decryptedNodesIterator) {
|
|
212
228
|
if (node.ok) {
|
|
213
229
|
yield node.value;
|
|
@@ -232,7 +248,9 @@ export class NodesAccess {
|
|
|
232
248
|
}
|
|
233
249
|
}
|
|
234
250
|
|
|
235
|
-
private async decryptNode(
|
|
251
|
+
private async decryptNode(
|
|
252
|
+
encryptedNode: EncryptedNode,
|
|
253
|
+
): Promise<{ node: DecryptedNode; keys?: DecryptedNodeKeys }> {
|
|
236
254
|
let parentKey;
|
|
237
255
|
try {
|
|
238
256
|
const parentKeys = await this.getParentKeys(encryptedNode);
|
|
@@ -299,18 +317,20 @@ export class NodesAccess {
|
|
|
299
317
|
return {
|
|
300
318
|
...unparsedNode,
|
|
301
319
|
isStale: false,
|
|
302
|
-
activeRevision: !unparsedNode.activeRevision?.ok
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
320
|
+
activeRevision: !unparsedNode.activeRevision?.ok
|
|
321
|
+
? unparsedNode.activeRevision
|
|
322
|
+
: resultOk({
|
|
323
|
+
uid: unparsedNode.activeRevision.value.uid,
|
|
324
|
+
state: unparsedNode.activeRevision.value.state,
|
|
325
|
+
creationTime: unparsedNode.activeRevision.value.creationTime,
|
|
326
|
+
storageSize: unparsedNode.activeRevision.value.storageSize,
|
|
327
|
+
contentAuthor: unparsedNode.activeRevision.value.contentAuthor,
|
|
328
|
+
thumbnails: unparsedNode.activeRevision.value.thumbnails,
|
|
329
|
+
...extendedAttributes,
|
|
330
|
+
}),
|
|
311
331
|
folder: undefined,
|
|
312
332
|
treeEventScopeId: splitNodeUid(unparsedNode.uid).volumeId,
|
|
313
|
-
}
|
|
333
|
+
};
|
|
314
334
|
}
|
|
315
335
|
|
|
316
336
|
const extendedAttributes = unparsedNode.folder?.extendedAttributes
|
|
@@ -321,14 +341,18 @@ export class NodesAccess {
|
|
|
321
341
|
name: nodeName,
|
|
322
342
|
isStale: false,
|
|
323
343
|
activeRevision: undefined,
|
|
324
|
-
folder: extendedAttributes
|
|
325
|
-
|
|
326
|
-
|
|
344
|
+
folder: extendedAttributes
|
|
345
|
+
? {
|
|
346
|
+
...extendedAttributes,
|
|
347
|
+
}
|
|
348
|
+
: undefined,
|
|
327
349
|
treeEventScopeId: splitNodeUid(unparsedNode.uid).volumeId,
|
|
328
|
-
}
|
|
350
|
+
};
|
|
329
351
|
}
|
|
330
352
|
|
|
331
|
-
async getParentKeys(
|
|
353
|
+
async getParentKeys(
|
|
354
|
+
node: Pick<DecryptedNode, 'parentUid' | 'shareId'>,
|
|
355
|
+
): Promise<Pick<DecryptedNodeKeys, 'key' | 'hashKey'>> {
|
|
332
356
|
if (node.parentUid) {
|
|
333
357
|
try {
|
|
334
358
|
return await this.getNodeKeys(node.parentUid);
|
|
@@ -345,7 +369,7 @@ export class NodesAccess {
|
|
|
345
369
|
if (node.shareId) {
|
|
346
370
|
return {
|
|
347
371
|
key: await this.shareService.getSharePrivateKey(node.shareId),
|
|
348
|
-
}
|
|
372
|
+
};
|
|
349
373
|
}
|
|
350
374
|
// This is bug that should not happen.
|
|
351
375
|
// API cannot provide node without parent or share.
|
|
@@ -365,11 +389,11 @@ export class NodesAccess {
|
|
|
365
389
|
}
|
|
366
390
|
|
|
367
391
|
async getNodePrivateAndSessionKeys(nodeUid: string): Promise<{
|
|
368
|
-
key: PrivateKey
|
|
369
|
-
passphrase: string
|
|
370
|
-
passphraseSessionKey: SessionKey
|
|
371
|
-
contentKeyPacketSessionKey?: SessionKey
|
|
372
|
-
nameSessionKey: SessionKey
|
|
392
|
+
key: PrivateKey;
|
|
393
|
+
passphrase: string;
|
|
394
|
+
passphraseSessionKey: SessionKey;
|
|
395
|
+
contentKeyPacketSessionKey?: SessionKey;
|
|
396
|
+
nameSessionKey: SessionKey;
|
|
373
397
|
}> {
|
|
374
398
|
const node = await this.getNode(nodeUid);
|
|
375
399
|
const { key: parentKey } = await this.getParentKeys(node);
|
|
@@ -385,10 +409,10 @@ export class NodesAccess {
|
|
|
385
409
|
}
|
|
386
410
|
|
|
387
411
|
async getRootNodeEmailKey(nodeUid: string): Promise<{
|
|
388
|
-
email: string
|
|
389
|
-
addressId: string
|
|
390
|
-
addressKey: PrivateKey
|
|
391
|
-
addressKeyId: string
|
|
412
|
+
email: string;
|
|
413
|
+
addressId: string;
|
|
414
|
+
addressKey: PrivateKey;
|
|
415
|
+
addressKeyId: string;
|
|
392
416
|
}> {
|
|
393
417
|
const rootNode = await this.getRootNode(nodeUid);
|
|
394
418
|
if (!rootNode.shareId) {
|
|
@@ -418,5 +442,5 @@ export class NodesAccess {
|
|
|
418
442
|
private async getRootNode(nodeUid: string): Promise<DecryptedNode> {
|
|
419
443
|
const node = await this.getNode(nodeUid);
|
|
420
444
|
return node.parentUid ? this.getRootNode(node.parentUid) : node;
|
|
421
|
-
}
|
|
445
|
+
}
|
|
422
446
|
}
|