@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,11 +1,20 @@
|
|
|
1
|
-
import { getMockLogger } from
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
1
|
+
import { getMockLogger } from '../../tests/logger';
|
|
2
|
+
import {
|
|
3
|
+
Member,
|
|
4
|
+
MemberRole,
|
|
5
|
+
NonProtonInvitation,
|
|
6
|
+
NonProtonInvitationState,
|
|
7
|
+
ProtonDriveAccount,
|
|
8
|
+
ProtonInvitation,
|
|
9
|
+
PublicLink,
|
|
10
|
+
resultOk,
|
|
11
|
+
} from '../../interface';
|
|
12
|
+
import { SharingAPIService } from './apiService';
|
|
13
|
+
import { SharingCryptoService } from './cryptoService';
|
|
14
|
+
import { SharesService, NodesService } from './interface';
|
|
15
|
+
import { SharingManagement } from './sharingManagement';
|
|
16
|
+
|
|
17
|
+
describe('SharingManagement', () => {
|
|
9
18
|
let apiService: SharingAPIService;
|
|
10
19
|
let cryptoService: SharingCryptoService;
|
|
11
20
|
let accountService: ProtonDriveAccount;
|
|
@@ -17,19 +26,19 @@ describe("SharingManagement", () => {
|
|
|
17
26
|
beforeEach(() => {
|
|
18
27
|
// @ts-expect-error No need to implement all methods for mocking
|
|
19
28
|
apiService = {
|
|
20
|
-
createStandardShare: jest.fn().mockReturnValue(
|
|
29
|
+
createStandardShare: jest.fn().mockReturnValue('newShareId'),
|
|
21
30
|
getShareInvitations: jest.fn().mockResolvedValue([]),
|
|
22
31
|
getShareExternalInvitations: jest.fn().mockResolvedValue([]),
|
|
23
32
|
getShareMembers: jest.fn().mockResolvedValue([]),
|
|
24
33
|
inviteProtonUser: jest.fn().mockImplementation((_, invitation) => ({
|
|
25
34
|
...invitation,
|
|
26
|
-
uid:
|
|
35
|
+
uid: 'created-invitation',
|
|
27
36
|
})),
|
|
28
37
|
updateInvitation: jest.fn(),
|
|
29
38
|
deleteInvitation: jest.fn(),
|
|
30
39
|
inviteExternalUser: jest.fn().mockImplementation((_, invitation) => ({
|
|
31
40
|
...invitation,
|
|
32
|
-
uid:
|
|
41
|
+
uid: 'created-external-invitation',
|
|
33
42
|
state: NonProtonInvitationState.Pending,
|
|
34
43
|
})),
|
|
35
44
|
updateExternalInvitation: jest.fn(),
|
|
@@ -42,55 +51,77 @@ describe("SharingManagement", () => {
|
|
|
42
51
|
resendInvitationEmail: jest.fn(),
|
|
43
52
|
resendExternalInvitationEmail: jest.fn(),
|
|
44
53
|
createPublicLink: jest.fn().mockResolvedValue({
|
|
45
|
-
uid:
|
|
46
|
-
publicUrl:
|
|
54
|
+
uid: 'publicLinkUid',
|
|
55
|
+
publicUrl: 'publicLinkUrl',
|
|
47
56
|
}),
|
|
48
57
|
updatePublicLink: jest.fn(),
|
|
49
|
-
}
|
|
58
|
+
};
|
|
50
59
|
// @ts-expect-error No need to implement all methods for mocking
|
|
51
60
|
cryptoService = {
|
|
52
|
-
generateShareKeys: jest
|
|
61
|
+
generateShareKeys: jest
|
|
62
|
+
.fn()
|
|
63
|
+
.mockResolvedValue({
|
|
64
|
+
shareKey: { encrypted: 'encrypted-key', decrypted: { passphraseSessionKey: 'pass-session-key' } },
|
|
65
|
+
}),
|
|
53
66
|
decryptShare: jest.fn().mockImplementation((share) => share),
|
|
54
67
|
decryptInvitation: jest.fn().mockImplementation((invitation) => invitation),
|
|
55
68
|
decryptExternalInvitation: jest.fn().mockImplementation((invitation) => invitation),
|
|
56
69
|
decryptMember: jest.fn().mockImplementation((member) => member),
|
|
57
|
-
encryptInvitation: jest.fn().mockImplementation(() => {
|
|
70
|
+
encryptInvitation: jest.fn().mockImplementation(() => {}),
|
|
58
71
|
encryptExternalInvitation: jest.fn().mockImplementation((invitation) => ({
|
|
59
72
|
...invitation,
|
|
60
|
-
base64ExternalInvitationSignature:
|
|
73
|
+
base64ExternalInvitationSignature: 'extenral-signature',
|
|
61
74
|
})),
|
|
62
75
|
decryptPublicLink: jest.fn().mockImplementation((publicLink) => publicLink),
|
|
63
|
-
generatePublicLinkPassword: jest.fn().mockResolvedValue(
|
|
76
|
+
generatePublicLinkPassword: jest.fn().mockResolvedValue('generatedPassword'),
|
|
64
77
|
encryptPublicLink: jest.fn().mockImplementation(() => ({
|
|
65
|
-
crypto:
|
|
66
|
-
srp:
|
|
78
|
+
crypto: 'publicLinkCrypto',
|
|
79
|
+
srp: 'publicLinkSrp',
|
|
67
80
|
})),
|
|
68
|
-
}
|
|
81
|
+
};
|
|
69
82
|
// @ts-expect-error No need to implement all methods for mocking
|
|
70
83
|
accountService = {
|
|
71
84
|
hasProtonAccount: jest.fn().mockResolvedValue(true),
|
|
72
|
-
}
|
|
85
|
+
};
|
|
73
86
|
// @ts-expect-error No need to implement all methods for mocking
|
|
74
87
|
sharesService = {
|
|
75
|
-
loadEncryptedShare: jest
|
|
76
|
-
|
|
77
|
-
|
|
88
|
+
loadEncryptedShare: jest
|
|
89
|
+
.fn()
|
|
90
|
+
.mockResolvedValue({
|
|
91
|
+
id: 'shareId',
|
|
92
|
+
addressId: 'addressId',
|
|
93
|
+
creatorEmail: 'address@example.com',
|
|
94
|
+
passphraseSessionKey: 'sharePassphraseSessionKey',
|
|
95
|
+
}),
|
|
96
|
+
getContextShareMemberEmailKey: jest
|
|
97
|
+
.fn()
|
|
98
|
+
.mockResolvedValue({ email: 'volume-email', addressId: 'addressId', addressKey: 'volume-key' }),
|
|
99
|
+
};
|
|
78
100
|
// @ts-expect-error No need to implement all methods for mocking
|
|
79
101
|
nodesService = {
|
|
80
|
-
getNode: jest
|
|
81
|
-
|
|
102
|
+
getNode: jest
|
|
103
|
+
.fn()
|
|
104
|
+
.mockImplementation((nodeUid) => ({ nodeUid, shareId: 'shareId', name: { ok: true, value: 'name' } })),
|
|
105
|
+
getNodeKeys: jest.fn().mockImplementation((nodeUid) => ({ key: 'node-key' })),
|
|
82
106
|
getNodePrivateAndSessionKeys: jest.fn().mockImplementation((nodeUid) => ({})),
|
|
83
|
-
getRootNodeEmailKey: jest.fn().mockResolvedValue({ email:
|
|
107
|
+
getRootNodeEmailKey: jest.fn().mockResolvedValue({ email: 'volume-email', addressKey: 'volume-key' }),
|
|
84
108
|
notifyNodeChanged: jest.fn(),
|
|
85
|
-
}
|
|
109
|
+
};
|
|
86
110
|
|
|
87
|
-
sharingManagement = new SharingManagement(
|
|
111
|
+
sharingManagement = new SharingManagement(
|
|
112
|
+
getMockLogger(),
|
|
113
|
+
apiService,
|
|
114
|
+
cryptoService,
|
|
115
|
+
accountService,
|
|
116
|
+
sharesService,
|
|
117
|
+
nodesService,
|
|
118
|
+
);
|
|
88
119
|
});
|
|
89
120
|
|
|
90
|
-
describe(
|
|
91
|
-
it(
|
|
92
|
-
nodesService.getNode = jest.fn().mockResolvedValue({ nodeUid:
|
|
93
|
-
const sharingInfo = await sharingManagement.getSharingInfo(
|
|
121
|
+
describe('getSharingInfo', () => {
|
|
122
|
+
it('should return empty sharing info for unshared node', async () => {
|
|
123
|
+
nodesService.getNode = jest.fn().mockResolvedValue({ nodeUid: 'nodeUid', shareId: undefined });
|
|
124
|
+
const sharingInfo = await sharingManagement.getSharingInfo('nodeUid');
|
|
94
125
|
|
|
95
126
|
expect(sharingInfo).toEqual(undefined);
|
|
96
127
|
expect(apiService.getShareInvitations).not.toHaveBeenCalled();
|
|
@@ -98,13 +129,11 @@ describe("SharingManagement", () => {
|
|
|
98
129
|
expect(apiService.getShareMembers).not.toHaveBeenCalled();
|
|
99
130
|
});
|
|
100
131
|
|
|
101
|
-
it(
|
|
102
|
-
const invitation = { uid:
|
|
103
|
-
apiService.getShareInvitations = jest.fn().mockResolvedValue([
|
|
104
|
-
invitation,
|
|
105
|
-
]);
|
|
132
|
+
it('should return invitations', async () => {
|
|
133
|
+
const invitation = { uid: 'invitaiton', addedByEmail: 'email' };
|
|
134
|
+
apiService.getShareInvitations = jest.fn().mockResolvedValue([invitation]);
|
|
106
135
|
|
|
107
|
-
const sharingInfo = await sharingManagement.getSharingInfo(
|
|
136
|
+
const sharingInfo = await sharingManagement.getSharingInfo('nodeUid');
|
|
108
137
|
|
|
109
138
|
expect(sharingInfo).toEqual({
|
|
110
139
|
protonInvitations: [invitation],
|
|
@@ -115,13 +144,11 @@ describe("SharingManagement", () => {
|
|
|
115
144
|
expect(cryptoService.decryptInvitation).toHaveBeenCalledWith(invitation);
|
|
116
145
|
});
|
|
117
146
|
|
|
118
|
-
it(
|
|
119
|
-
const externalInvitation = { uid:
|
|
120
|
-
apiService.getShareExternalInvitations = jest.fn().mockResolvedValue([
|
|
121
|
-
externalInvitation,
|
|
122
|
-
]);
|
|
147
|
+
it('should return external invitations', async () => {
|
|
148
|
+
const externalInvitation = { uid: 'external-invitation', addedByEmail: 'email' };
|
|
149
|
+
apiService.getShareExternalInvitations = jest.fn().mockResolvedValue([externalInvitation]);
|
|
123
150
|
|
|
124
|
-
const sharingInfo = await sharingManagement.getSharingInfo(
|
|
151
|
+
const sharingInfo = await sharingManagement.getSharingInfo('nodeUid');
|
|
125
152
|
|
|
126
153
|
expect(sharingInfo).toEqual({
|
|
127
154
|
protonInvitations: [],
|
|
@@ -132,13 +159,11 @@ describe("SharingManagement", () => {
|
|
|
132
159
|
expect(cryptoService.decryptExternalInvitation).toHaveBeenCalledWith(externalInvitation);
|
|
133
160
|
});
|
|
134
161
|
|
|
135
|
-
it(
|
|
136
|
-
const member = { uid:
|
|
137
|
-
apiService.getShareMembers = jest.fn().mockResolvedValue([
|
|
138
|
-
member,
|
|
139
|
-
]);
|
|
162
|
+
it('should return members', async () => {
|
|
163
|
+
const member = { uid: 'member', addedByEmail: 'email' };
|
|
164
|
+
apiService.getShareMembers = jest.fn().mockResolvedValue([member]);
|
|
140
165
|
|
|
141
|
-
const sharingInfo = await sharingManagement.getSharingInfo(
|
|
166
|
+
const sharingInfo = await sharingManagement.getSharingInfo('nodeUid');
|
|
142
167
|
|
|
143
168
|
expect(sharingInfo).toEqual({
|
|
144
169
|
protonInvitations: [],
|
|
@@ -149,13 +174,13 @@ describe("SharingManagement", () => {
|
|
|
149
174
|
expect(cryptoService.decryptMember).toHaveBeenCalledWith(member);
|
|
150
175
|
});
|
|
151
176
|
|
|
152
|
-
it(
|
|
177
|
+
it('should return public link', async () => {
|
|
153
178
|
const publicLink = {
|
|
154
179
|
uid: 'shared~publicLink',
|
|
155
|
-
}
|
|
180
|
+
};
|
|
156
181
|
apiService.getPublicLink = jest.fn().mockResolvedValue(publicLink);
|
|
157
182
|
|
|
158
|
-
const sharingInfo = await sharingManagement.getSharingInfo(
|
|
183
|
+
const sharingInfo = await sharingManagement.getSharingInfo('nodeUid');
|
|
159
184
|
|
|
160
185
|
expect(sharingInfo).toEqual({
|
|
161
186
|
protonInvitations: [],
|
|
@@ -167,22 +192,30 @@ describe("SharingManagement", () => {
|
|
|
167
192
|
});
|
|
168
193
|
});
|
|
169
194
|
|
|
170
|
-
describe(
|
|
171
|
-
const nodeUid =
|
|
195
|
+
describe('shareNode with share creation', () => {
|
|
196
|
+
const nodeUid = 'volumeId~nodeUid';
|
|
172
197
|
|
|
173
|
-
it(
|
|
174
|
-
nodesService.getNode = jest
|
|
198
|
+
it('should create share if no exists', async () => {
|
|
199
|
+
nodesService.getNode = jest
|
|
200
|
+
.fn()
|
|
201
|
+
.mockImplementation((nodeUid) => ({
|
|
202
|
+
nodeUid,
|
|
203
|
+
parentUid: 'parentUid',
|
|
204
|
+
name: { ok: true, value: 'name' },
|
|
205
|
+
}));
|
|
175
206
|
nodesService.notifyNodeChanged = jest.fn();
|
|
176
207
|
|
|
177
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: [
|
|
208
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: ['email'] });
|
|
178
209
|
|
|
179
210
|
expect(sharingInfo).toEqual({
|
|
180
|
-
protonInvitations: [
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
211
|
+
protonInvitations: [
|
|
212
|
+
{
|
|
213
|
+
uid: 'created-invitation',
|
|
214
|
+
addedByEmail: { ok: true, value: 'volume-email' },
|
|
215
|
+
inviteeEmail: 'email',
|
|
216
|
+
role: 'viewer',
|
|
217
|
+
},
|
|
218
|
+
],
|
|
186
219
|
nonProtonInvitations: [],
|
|
187
220
|
members: [],
|
|
188
221
|
publicLink: undefined,
|
|
@@ -191,10 +224,10 @@ describe("SharingManagement", () => {
|
|
|
191
224
|
expect(apiService.inviteProtonUser).toHaveBeenCalled();
|
|
192
225
|
expect(nodesService.notifyNodeChanged).toHaveBeenCalledWith(nodeUid);
|
|
193
226
|
});
|
|
194
|
-
})
|
|
227
|
+
});
|
|
195
228
|
|
|
196
|
-
describe(
|
|
197
|
-
const nodeUid =
|
|
229
|
+
describe('shareNode with share re-use', () => {
|
|
230
|
+
const nodeUid = 'volumeId~nodeUid';
|
|
198
231
|
|
|
199
232
|
let invitation: ProtonInvitation;
|
|
200
233
|
let externalInvitation: NonProtonInvitation;
|
|
@@ -202,56 +235,53 @@ describe("SharingManagement", () => {
|
|
|
202
235
|
|
|
203
236
|
beforeEach(async () => {
|
|
204
237
|
invitation = {
|
|
205
|
-
uid:
|
|
206
|
-
addedByEmail: resultOk(
|
|
207
|
-
inviteeEmail:
|
|
238
|
+
uid: 'invitation',
|
|
239
|
+
addedByEmail: resultOk('added-email'),
|
|
240
|
+
inviteeEmail: 'internal-email',
|
|
208
241
|
role: MemberRole.Viewer,
|
|
209
242
|
invitationTime: new Date(),
|
|
210
243
|
};
|
|
211
244
|
externalInvitation = {
|
|
212
|
-
uid:
|
|
213
|
-
addedByEmail: resultOk(
|
|
214
|
-
inviteeEmail:
|
|
245
|
+
uid: 'external-invitation',
|
|
246
|
+
addedByEmail: resultOk('added-email'),
|
|
247
|
+
inviteeEmail: 'external-email',
|
|
215
248
|
role: MemberRole.Viewer,
|
|
216
249
|
invitationTime: new Date(),
|
|
217
250
|
state: NonProtonInvitationState.Pending,
|
|
218
251
|
};
|
|
219
252
|
member = {
|
|
220
|
-
uid:
|
|
221
|
-
addedByEmail: resultOk(
|
|
222
|
-
inviteeEmail:
|
|
253
|
+
uid: 'member',
|
|
254
|
+
addedByEmail: resultOk('added-email'),
|
|
255
|
+
inviteeEmail: 'member-email',
|
|
223
256
|
role: MemberRole.Viewer,
|
|
224
257
|
invitationTime: new Date(),
|
|
225
258
|
};
|
|
226
259
|
|
|
227
|
-
apiService.getShareInvitations = jest.fn().mockResolvedValue([
|
|
228
|
-
invitation,
|
|
229
|
-
]);
|
|
260
|
+
apiService.getShareInvitations = jest.fn().mockResolvedValue([invitation]);
|
|
230
261
|
|
|
231
|
-
apiService.getShareExternalInvitations = jest.fn().mockResolvedValue([
|
|
232
|
-
externalInvitation,
|
|
233
|
-
]);
|
|
262
|
+
apiService.getShareExternalInvitations = jest.fn().mockResolvedValue([externalInvitation]);
|
|
234
263
|
|
|
235
|
-
apiService.getShareMembers = jest.fn().mockResolvedValue([
|
|
236
|
-
member,
|
|
237
|
-
]);
|
|
264
|
+
apiService.getShareMembers = jest.fn().mockResolvedValue([member]);
|
|
238
265
|
});
|
|
239
266
|
|
|
240
|
-
describe(
|
|
267
|
+
describe('invitations', () => {
|
|
241
268
|
beforeEach(() => {
|
|
242
269
|
accountService.hasProtonAccount = jest.fn().mockResolvedValue(true);
|
|
243
270
|
});
|
|
244
271
|
|
|
245
|
-
it(
|
|
246
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: [
|
|
272
|
+
it('should share node with proton email with default role', async () => {
|
|
273
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: ['email'] });
|
|
247
274
|
|
|
248
275
|
expect(sharingInfo).toEqual({
|
|
249
|
-
protonInvitations: [
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
276
|
+
protonInvitations: [
|
|
277
|
+
invitation,
|
|
278
|
+
{
|
|
279
|
+
uid: 'created-invitation',
|
|
280
|
+
addedByEmail: { ok: true, value: 'volume-email' },
|
|
281
|
+
inviteeEmail: 'email',
|
|
282
|
+
role: 'viewer',
|
|
283
|
+
},
|
|
284
|
+
],
|
|
255
285
|
nonProtonInvitations: [externalInvitation],
|
|
256
286
|
members: [member],
|
|
257
287
|
publicLink: undefined,
|
|
@@ -260,16 +290,21 @@ describe("SharingManagement", () => {
|
|
|
260
290
|
expect(apiService.inviteProtonUser).toHaveBeenCalled();
|
|
261
291
|
});
|
|
262
292
|
|
|
263
|
-
it(
|
|
264
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
293
|
+
it('should share node with proton email with specific role', async () => {
|
|
294
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
295
|
+
users: [{ email: 'email', role: MemberRole.Editor }],
|
|
296
|
+
});
|
|
265
297
|
|
|
266
298
|
expect(sharingInfo).toEqual({
|
|
267
|
-
protonInvitations: [
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
299
|
+
protonInvitations: [
|
|
300
|
+
invitation,
|
|
301
|
+
{
|
|
302
|
+
uid: 'created-invitation',
|
|
303
|
+
addedByEmail: { ok: true, value: 'volume-email' },
|
|
304
|
+
inviteeEmail: 'email',
|
|
305
|
+
role: 'editor',
|
|
306
|
+
},
|
|
307
|
+
],
|
|
273
308
|
nonProtonInvitations: [externalInvitation],
|
|
274
309
|
members: [member],
|
|
275
310
|
publicLink: undefined,
|
|
@@ -278,14 +313,18 @@ describe("SharingManagement", () => {
|
|
|
278
313
|
expect(apiService.inviteProtonUser).toHaveBeenCalled();
|
|
279
314
|
});
|
|
280
315
|
|
|
281
|
-
it(
|
|
282
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
316
|
+
it('should update existing role', async () => {
|
|
317
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
318
|
+
users: [{ email: 'internal-email', role: MemberRole.Editor }],
|
|
319
|
+
});
|
|
283
320
|
|
|
284
321
|
expect(sharingInfo).toEqual({
|
|
285
|
-
protonInvitations: [
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
322
|
+
protonInvitations: [
|
|
323
|
+
{
|
|
324
|
+
...invitation,
|
|
325
|
+
role: 'editor',
|
|
326
|
+
},
|
|
327
|
+
],
|
|
289
328
|
nonProtonInvitations: [externalInvitation],
|
|
290
329
|
members: [member],
|
|
291
330
|
publicLink: undefined,
|
|
@@ -294,8 +333,10 @@ describe("SharingManagement", () => {
|
|
|
294
333
|
expect(apiService.inviteProtonUser).not.toHaveBeenCalled();
|
|
295
334
|
});
|
|
296
335
|
|
|
297
|
-
it(
|
|
298
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
336
|
+
it('should be no-op if no change', async () => {
|
|
337
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
338
|
+
users: [{ email: 'internal-email', role: MemberRole.Viewer }],
|
|
339
|
+
});
|
|
299
340
|
|
|
300
341
|
expect(sharingInfo).toEqual({
|
|
301
342
|
protonInvitations: [invitation],
|
|
@@ -308,23 +349,26 @@ describe("SharingManagement", () => {
|
|
|
308
349
|
});
|
|
309
350
|
});
|
|
310
351
|
|
|
311
|
-
describe(
|
|
352
|
+
describe('external invitations', () => {
|
|
312
353
|
beforeEach(() => {
|
|
313
354
|
accountService.hasProtonAccount = jest.fn().mockResolvedValue(false);
|
|
314
355
|
});
|
|
315
356
|
|
|
316
|
-
it(
|
|
317
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: [
|
|
357
|
+
it('should share node with external email with default role', async () => {
|
|
358
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: ['email'] });
|
|
318
359
|
|
|
319
360
|
expect(sharingInfo).toEqual({
|
|
320
361
|
protonInvitations: [invitation],
|
|
321
|
-
nonProtonInvitations: [
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
362
|
+
nonProtonInvitations: [
|
|
363
|
+
externalInvitation,
|
|
364
|
+
{
|
|
365
|
+
uid: 'created-external-invitation',
|
|
366
|
+
addedByEmail: { ok: true, value: 'volume-email' },
|
|
367
|
+
inviteeEmail: 'email',
|
|
368
|
+
role: 'viewer',
|
|
369
|
+
state: 'pending',
|
|
370
|
+
},
|
|
371
|
+
],
|
|
328
372
|
members: [member],
|
|
329
373
|
publicLink: undefined,
|
|
330
374
|
});
|
|
@@ -332,18 +376,23 @@ describe("SharingManagement", () => {
|
|
|
332
376
|
expect(apiService.inviteExternalUser).toHaveBeenCalled();
|
|
333
377
|
});
|
|
334
378
|
|
|
335
|
-
it(
|
|
336
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
379
|
+
it('should share node with external email with specific role', async () => {
|
|
380
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
381
|
+
users: [{ email: 'email', role: MemberRole.Editor }],
|
|
382
|
+
});
|
|
337
383
|
|
|
338
384
|
expect(sharingInfo).toEqual({
|
|
339
385
|
protonInvitations: [invitation],
|
|
340
|
-
nonProtonInvitations: [
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
386
|
+
nonProtonInvitations: [
|
|
387
|
+
externalInvitation,
|
|
388
|
+
{
|
|
389
|
+
uid: 'created-external-invitation',
|
|
390
|
+
addedByEmail: { ok: true, value: 'volume-email' },
|
|
391
|
+
inviteeEmail: 'email',
|
|
392
|
+
role: 'editor',
|
|
393
|
+
state: 'pending',
|
|
394
|
+
},
|
|
395
|
+
],
|
|
347
396
|
members: [member],
|
|
348
397
|
publicLink: undefined,
|
|
349
398
|
});
|
|
@@ -351,15 +400,19 @@ describe("SharingManagement", () => {
|
|
|
351
400
|
expect(apiService.inviteExternalUser).toHaveBeenCalled();
|
|
352
401
|
});
|
|
353
402
|
|
|
354
|
-
it(
|
|
355
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
403
|
+
it('should update existing role', async () => {
|
|
404
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
405
|
+
users: [{ email: 'external-email', role: MemberRole.Editor }],
|
|
406
|
+
});
|
|
356
407
|
|
|
357
408
|
expect(sharingInfo).toEqual({
|
|
358
409
|
protonInvitations: [invitation],
|
|
359
|
-
nonProtonInvitations: [
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
410
|
+
nonProtonInvitations: [
|
|
411
|
+
{
|
|
412
|
+
...externalInvitation,
|
|
413
|
+
role: 'editor',
|
|
414
|
+
},
|
|
415
|
+
],
|
|
363
416
|
members: [member],
|
|
364
417
|
publicLink: undefined,
|
|
365
418
|
});
|
|
@@ -367,8 +420,10 @@ describe("SharingManagement", () => {
|
|
|
367
420
|
expect(apiService.inviteExternalUser).not.toHaveBeenCalled();
|
|
368
421
|
});
|
|
369
422
|
|
|
370
|
-
it(
|
|
371
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
423
|
+
it('should be no-op if no change', async () => {
|
|
424
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
425
|
+
users: [{ email: 'external-email', role: MemberRole.Viewer }],
|
|
426
|
+
});
|
|
372
427
|
|
|
373
428
|
expect(sharingInfo).toEqual({
|
|
374
429
|
protonInvitations: [invitation],
|
|
@@ -381,54 +436,70 @@ describe("SharingManagement", () => {
|
|
|
381
436
|
});
|
|
382
437
|
});
|
|
383
438
|
|
|
384
|
-
describe(
|
|
439
|
+
describe('mix of internal and external invitations', () => {
|
|
385
440
|
beforeEach(() => {
|
|
386
|
-
accountService.hasProtonAccount = jest.fn()
|
|
387
|
-
.mockResolvedValueOnce(true)
|
|
388
|
-
.mockResolvedValueOnce(false);
|
|
441
|
+
accountService.hasProtonAccount = jest.fn().mockResolvedValueOnce(true).mockResolvedValueOnce(false);
|
|
389
442
|
});
|
|
390
443
|
|
|
391
|
-
it(
|
|
392
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: [
|
|
444
|
+
it('should share node with proton and external email with default role', async () => {
|
|
445
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, { users: ['email', 'email2'] });
|
|
393
446
|
|
|
394
447
|
expect(sharingInfo).toEqual({
|
|
395
|
-
protonInvitations: [
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
448
|
+
protonInvitations: [
|
|
449
|
+
invitation,
|
|
450
|
+
{
|
|
451
|
+
uid: 'created-invitation',
|
|
452
|
+
addedByEmail: { ok: true, value: 'volume-email' },
|
|
453
|
+
inviteeEmail: 'email',
|
|
454
|
+
role: 'viewer',
|
|
455
|
+
},
|
|
456
|
+
],
|
|
457
|
+
nonProtonInvitations: [
|
|
458
|
+
externalInvitation,
|
|
459
|
+
{
|
|
460
|
+
uid: 'created-external-invitation',
|
|
461
|
+
addedByEmail: { ok: true, value: 'volume-email' },
|
|
462
|
+
inviteeEmail: 'email2',
|
|
463
|
+
role: 'viewer',
|
|
464
|
+
state: 'pending',
|
|
465
|
+
},
|
|
466
|
+
],
|
|
408
467
|
members: [member],
|
|
409
468
|
publicLink: undefined,
|
|
410
469
|
});
|
|
411
470
|
expect(apiService.updateInvitation).not.toHaveBeenCalled();
|
|
412
|
-
expect(apiService.inviteProtonUser).toHaveBeenCalledWith(
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
471
|
+
expect(apiService.inviteProtonUser).toHaveBeenCalledWith(
|
|
472
|
+
'shareId',
|
|
473
|
+
expect.objectContaining({
|
|
474
|
+
inviteeEmail: 'email',
|
|
475
|
+
}),
|
|
476
|
+
expect.anything(),
|
|
477
|
+
);
|
|
478
|
+
expect(apiService.inviteExternalUser).toHaveBeenCalledWith(
|
|
479
|
+
'shareId',
|
|
480
|
+
expect.objectContaining({
|
|
481
|
+
inviteeEmail: 'email2',
|
|
482
|
+
}),
|
|
483
|
+
expect.anything(),
|
|
484
|
+
);
|
|
418
485
|
});
|
|
419
486
|
});
|
|
420
487
|
|
|
421
|
-
describe(
|
|
422
|
-
it(
|
|
423
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
488
|
+
describe('members', () => {
|
|
489
|
+
it('should update member via proton user', async () => {
|
|
490
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
491
|
+
users: [{ email: 'member-email', role: MemberRole.Editor }],
|
|
492
|
+
});
|
|
424
493
|
|
|
425
494
|
expect(sharingInfo).toEqual({
|
|
426
495
|
protonInvitations: [invitation],
|
|
427
496
|
nonProtonInvitations: [externalInvitation],
|
|
428
|
-
members: [
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
497
|
+
members: [
|
|
498
|
+
{
|
|
499
|
+
...member,
|
|
500
|
+
role: 'editor',
|
|
501
|
+
},
|
|
502
|
+
],
|
|
432
503
|
publicLink: undefined,
|
|
433
504
|
});
|
|
434
505
|
expect(apiService.updateMember).toHaveBeenCalled();
|
|
@@ -436,8 +507,10 @@ describe("SharingManagement", () => {
|
|
|
436
507
|
expect(apiService.inviteProtonUser).not.toHaveBeenCalled();
|
|
437
508
|
});
|
|
438
509
|
|
|
439
|
-
it(
|
|
440
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
510
|
+
it('should be no-op if no change via proton user', async () => {
|
|
511
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
512
|
+
users: [{ email: 'member-email', role: MemberRole.Viewer }],
|
|
513
|
+
});
|
|
441
514
|
|
|
442
515
|
expect(sharingInfo).toEqual({
|
|
443
516
|
protonInvitations: [invitation],
|
|
@@ -450,16 +523,20 @@ describe("SharingManagement", () => {
|
|
|
450
523
|
expect(apiService.inviteProtonUser).not.toHaveBeenCalled();
|
|
451
524
|
});
|
|
452
525
|
|
|
453
|
-
it(
|
|
454
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
526
|
+
it('should update member via non-proton user', async () => {
|
|
527
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
528
|
+
users: [{ email: 'member-email', role: MemberRole.Editor }],
|
|
529
|
+
});
|
|
455
530
|
|
|
456
531
|
expect(sharingInfo).toEqual({
|
|
457
532
|
protonInvitations: [invitation],
|
|
458
533
|
nonProtonInvitations: [externalInvitation],
|
|
459
|
-
members: [
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
534
|
+
members: [
|
|
535
|
+
{
|
|
536
|
+
...member,
|
|
537
|
+
role: 'editor',
|
|
538
|
+
},
|
|
539
|
+
],
|
|
463
540
|
publicLink: undefined,
|
|
464
541
|
});
|
|
465
542
|
expect(apiService.updateMember).toHaveBeenCalled();
|
|
@@ -467,8 +544,10 @@ describe("SharingManagement", () => {
|
|
|
467
544
|
expect(apiService.inviteProtonUser).not.toHaveBeenCalled();
|
|
468
545
|
});
|
|
469
546
|
|
|
470
|
-
it(
|
|
471
|
-
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
547
|
+
it('should be no-op if no change via non-proton user', async () => {
|
|
548
|
+
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
549
|
+
users: [{ email: 'member-email', role: MemberRole.Viewer }],
|
|
550
|
+
});
|
|
472
551
|
|
|
473
552
|
expect(sharingInfo).toEqual({
|
|
474
553
|
protonInvitations: [invitation],
|
|
@@ -482,8 +561,8 @@ describe("SharingManagement", () => {
|
|
|
482
561
|
});
|
|
483
562
|
});
|
|
484
563
|
|
|
485
|
-
describe(
|
|
486
|
-
it(
|
|
564
|
+
describe('public link', () => {
|
|
565
|
+
it('should share node with public link', async () => {
|
|
487
566
|
jest.useFakeTimers();
|
|
488
567
|
jest.setSystemTime(new Date('2025-01-01'));
|
|
489
568
|
|
|
@@ -500,35 +579,42 @@ describe("SharingManagement", () => {
|
|
|
500
579
|
nonProtonInvitations: [externalInvitation],
|
|
501
580
|
members: [member],
|
|
502
581
|
publicLink: {
|
|
503
|
-
uid:
|
|
582
|
+
uid: 'publicLinkUid',
|
|
504
583
|
role: MemberRole.Viewer,
|
|
505
|
-
url:
|
|
584
|
+
url: 'publicLinkUrl#generatedPassword',
|
|
506
585
|
creationTime: new Date(),
|
|
507
586
|
expirationTime: undefined,
|
|
508
587
|
customPassword: undefined,
|
|
509
|
-
creatorEmail:
|
|
588
|
+
creatorEmail: 'volume-email',
|
|
510
589
|
numberOfInitializedDownloads: 0,
|
|
511
590
|
},
|
|
512
591
|
});
|
|
513
592
|
expect(cryptoService.generatePublicLinkPassword).toHaveBeenCalled();
|
|
514
|
-
expect(cryptoService.encryptPublicLink).toHaveBeenCalledWith(
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
593
|
+
expect(cryptoService.encryptPublicLink).toHaveBeenCalledWith(
|
|
594
|
+
'volume-email',
|
|
595
|
+
'sharePassphraseSessionKey',
|
|
596
|
+
'generatedPassword',
|
|
597
|
+
);
|
|
598
|
+
expect(apiService.createPublicLink).toHaveBeenCalledWith(
|
|
599
|
+
'shareId',
|
|
600
|
+
expect.objectContaining({
|
|
601
|
+
role: MemberRole.Viewer,
|
|
602
|
+
includesCustomPassword: false,
|
|
603
|
+
expirationTime: undefined,
|
|
604
|
+
crypto: 'publicLinkCrypto',
|
|
605
|
+
srp: 'publicLinkSrp',
|
|
606
|
+
}),
|
|
607
|
+
);
|
|
522
608
|
});
|
|
523
609
|
|
|
524
|
-
it(
|
|
610
|
+
it('should share node with custom password and expiration', async () => {
|
|
525
611
|
jest.useFakeTimers();
|
|
526
612
|
jest.setSystemTime(new Date('2025-01-01'));
|
|
527
613
|
|
|
528
614
|
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
529
615
|
publicLink: {
|
|
530
616
|
role: MemberRole.Viewer,
|
|
531
|
-
customPassword:
|
|
617
|
+
customPassword: 'customPassword',
|
|
532
618
|
expiration: new Date('2025-01-02'),
|
|
533
619
|
},
|
|
534
620
|
});
|
|
@@ -538,46 +624,53 @@ describe("SharingManagement", () => {
|
|
|
538
624
|
nonProtonInvitations: [externalInvitation],
|
|
539
625
|
members: [member],
|
|
540
626
|
publicLink: {
|
|
541
|
-
uid:
|
|
627
|
+
uid: 'publicLinkUid',
|
|
542
628
|
role: MemberRole.Viewer,
|
|
543
|
-
url:
|
|
629
|
+
url: 'publicLinkUrl#generatedPassword',
|
|
544
630
|
creationTime: new Date(),
|
|
545
631
|
expirationTime: new Date('2025-01-02'),
|
|
546
|
-
customPassword:
|
|
547
|
-
creatorEmail:
|
|
632
|
+
customPassword: 'customPassword',
|
|
633
|
+
creatorEmail: 'volume-email',
|
|
548
634
|
numberOfInitializedDownloads: 0,
|
|
549
635
|
},
|
|
550
636
|
});
|
|
551
637
|
expect(cryptoService.generatePublicLinkPassword).toHaveBeenCalled();
|
|
552
|
-
expect(cryptoService.encryptPublicLink).toHaveBeenCalledWith(
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
638
|
+
expect(cryptoService.encryptPublicLink).toHaveBeenCalledWith(
|
|
639
|
+
'volume-email',
|
|
640
|
+
'sharePassphraseSessionKey',
|
|
641
|
+
'generatedPasswordcustomPassword',
|
|
642
|
+
);
|
|
643
|
+
expect(apiService.createPublicLink).toHaveBeenCalledWith(
|
|
644
|
+
'shareId',
|
|
645
|
+
expect.objectContaining({
|
|
646
|
+
role: MemberRole.Viewer,
|
|
647
|
+
includesCustomPassword: true,
|
|
648
|
+
expirationTime: 1735776000,
|
|
649
|
+
crypto: 'publicLinkCrypto',
|
|
650
|
+
srp: 'publicLinkSrp',
|
|
651
|
+
}),
|
|
652
|
+
);
|
|
560
653
|
});
|
|
561
654
|
|
|
562
|
-
it(
|
|
655
|
+
it('should update public link with custom password and expiration', async () => {
|
|
563
656
|
jest.useFakeTimers();
|
|
564
657
|
jest.setSystemTime(new Date('2025-01-01'));
|
|
565
658
|
|
|
566
659
|
const publicLink = {
|
|
567
660
|
uid: 'publicLinkUid',
|
|
568
|
-
url:
|
|
661
|
+
url: 'publicLinkUrl#generatedpas', // Generated password must be 12 chararacters long.
|
|
569
662
|
creationTime: new Date('2025-01-01'),
|
|
570
663
|
role: MemberRole.Viewer,
|
|
571
664
|
customPassword: undefined,
|
|
572
665
|
expirationTime: undefined,
|
|
573
|
-
creatorEmail:
|
|
574
|
-
}
|
|
666
|
+
creatorEmail: 'publicLinkCreatorEmail',
|
|
667
|
+
};
|
|
575
668
|
apiService.getPublicLink = jest.fn().mockResolvedValue(publicLink);
|
|
576
669
|
|
|
577
670
|
const sharingInfo = await sharingManagement.shareNode(nodeUid, {
|
|
578
671
|
publicLink: {
|
|
579
672
|
role: MemberRole.Editor,
|
|
580
|
-
customPassword:
|
|
673
|
+
customPassword: 'customPassword',
|
|
581
674
|
expiration: new Date('2025-01-02'),
|
|
582
675
|
},
|
|
583
676
|
});
|
|
@@ -587,65 +680,78 @@ describe("SharingManagement", () => {
|
|
|
587
680
|
nonProtonInvitations: [externalInvitation],
|
|
588
681
|
members: [member],
|
|
589
682
|
publicLink: {
|
|
590
|
-
uid:
|
|
683
|
+
uid: 'publicLinkUid',
|
|
591
684
|
role: MemberRole.Editor,
|
|
592
|
-
url:
|
|
685
|
+
url: 'publicLinkUrl#generatedpas',
|
|
593
686
|
creationTime: new Date('2025-01-01'),
|
|
594
687
|
expirationTime: new Date('2025-01-02'),
|
|
595
|
-
customPassword:
|
|
596
|
-
creatorEmail:
|
|
688
|
+
customPassword: 'customPassword',
|
|
689
|
+
creatorEmail: 'publicLinkCreatorEmail',
|
|
597
690
|
},
|
|
598
691
|
});
|
|
599
|
-
expect(cryptoService.encryptPublicLink).toHaveBeenCalledWith(
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
692
|
+
expect(cryptoService.encryptPublicLink).toHaveBeenCalledWith(
|
|
693
|
+
'publicLinkCreatorEmail',
|
|
694
|
+
'sharePassphraseSessionKey',
|
|
695
|
+
'generatedpascustomPassword',
|
|
696
|
+
);
|
|
697
|
+
expect(apiService.updatePublicLink).toHaveBeenCalledWith(
|
|
698
|
+
'publicLinkUid',
|
|
699
|
+
expect.objectContaining({
|
|
700
|
+
role: MemberRole.Editor,
|
|
701
|
+
includesCustomPassword: true,
|
|
702
|
+
expirationTime: 1735776000,
|
|
703
|
+
crypto: 'publicLinkCrypto',
|
|
704
|
+
srp: 'publicLinkSrp',
|
|
705
|
+
}),
|
|
706
|
+
);
|
|
607
707
|
});
|
|
608
708
|
|
|
609
|
-
it(
|
|
709
|
+
it('should not allow updating legacy public link', async () => {
|
|
610
710
|
apiService.getPublicLink = jest.fn().mockResolvedValue({
|
|
611
711
|
uid: 'publicLinkUid',
|
|
612
|
-
url:
|
|
712
|
+
url: 'publicLinkUrl#aaa', // Legacy public links doesn't have 12 chars.
|
|
613
713
|
});
|
|
614
714
|
|
|
615
|
-
await expect(
|
|
616
|
-
|
|
617
|
-
|
|
715
|
+
await expect(
|
|
716
|
+
sharingManagement.shareNode(nodeUid, {
|
|
717
|
+
publicLink: true,
|
|
718
|
+
}),
|
|
719
|
+
).rejects.toThrow('Legacy public link cannot be updated. Please re-create a new public link.');
|
|
618
720
|
});
|
|
619
721
|
|
|
620
|
-
it(
|
|
722
|
+
it('should not allow updating legacy public link without generated password', async () => {
|
|
621
723
|
apiService.getPublicLink = jest.fn().mockResolvedValue({
|
|
622
724
|
uid: 'publicLinkUid',
|
|
623
|
-
url:
|
|
725
|
+
url: 'publicLinkUrl',
|
|
624
726
|
});
|
|
625
727
|
|
|
626
|
-
await expect(
|
|
627
|
-
|
|
628
|
-
|
|
728
|
+
await expect(
|
|
729
|
+
sharingManagement.shareNode(nodeUid, {
|
|
730
|
+
publicLink: true,
|
|
731
|
+
}),
|
|
732
|
+
).rejects.toThrow('Legacy public link cannot be updated. Please re-create a new public link.');
|
|
629
733
|
});
|
|
630
734
|
|
|
631
|
-
it(
|
|
735
|
+
it('should not allow creating public link with expiration in the past', async () => {
|
|
632
736
|
jest.useFakeTimers();
|
|
633
737
|
jest.setSystemTime(new Date('2025-01-01'));
|
|
634
738
|
|
|
635
|
-
await expect(
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
739
|
+
await expect(
|
|
740
|
+
sharingManagement.shareNode(nodeUid, {
|
|
741
|
+
publicLink: {
|
|
742
|
+
role: MemberRole.Viewer,
|
|
743
|
+
expiration: new Date('2024-01-01'),
|
|
744
|
+
},
|
|
745
|
+
}),
|
|
746
|
+
).rejects.toThrow('Expiration date cannot be in the past');
|
|
641
747
|
expect(apiService.createStandardShare).not.toHaveBeenCalled();
|
|
642
748
|
expect(apiService.createPublicLink).not.toHaveBeenCalled();
|
|
643
749
|
});
|
|
644
750
|
});
|
|
645
751
|
});
|
|
646
752
|
|
|
647
|
-
describe(
|
|
648
|
-
const nodeUid =
|
|
753
|
+
describe('unshareNode', () => {
|
|
754
|
+
const nodeUid = 'volumeId~nodeUid';
|
|
649
755
|
|
|
650
756
|
let invitation: ProtonInvitation;
|
|
651
757
|
let externalInvitation: NonProtonInvitation;
|
|
@@ -654,49 +760,43 @@ describe("SharingManagement", () => {
|
|
|
654
760
|
|
|
655
761
|
beforeEach(async () => {
|
|
656
762
|
invitation = {
|
|
657
|
-
uid:
|
|
658
|
-
addedByEmail: resultOk(
|
|
659
|
-
inviteeEmail:
|
|
763
|
+
uid: 'invitation',
|
|
764
|
+
addedByEmail: resultOk('added-email'),
|
|
765
|
+
inviteeEmail: 'internal-email',
|
|
660
766
|
role: MemberRole.Viewer,
|
|
661
767
|
invitationTime: new Date(),
|
|
662
768
|
};
|
|
663
769
|
externalInvitation = {
|
|
664
|
-
uid:
|
|
665
|
-
addedByEmail: resultOk(
|
|
666
|
-
inviteeEmail:
|
|
770
|
+
uid: 'external-invitation',
|
|
771
|
+
addedByEmail: resultOk('added-email'),
|
|
772
|
+
inviteeEmail: 'external-email',
|
|
667
773
|
role: MemberRole.Viewer,
|
|
668
774
|
invitationTime: new Date(),
|
|
669
775
|
state: NonProtonInvitationState.Pending,
|
|
670
776
|
};
|
|
671
777
|
member = {
|
|
672
|
-
uid:
|
|
673
|
-
addedByEmail: resultOk(
|
|
674
|
-
inviteeEmail:
|
|
778
|
+
uid: 'member',
|
|
779
|
+
addedByEmail: resultOk('added-email'),
|
|
780
|
+
inviteeEmail: 'member-email',
|
|
675
781
|
role: MemberRole.Viewer,
|
|
676
782
|
invitationTime: new Date(),
|
|
677
783
|
};
|
|
678
784
|
publicLink = {
|
|
679
|
-
uid:
|
|
785
|
+
uid: 'publicLink',
|
|
680
786
|
creationTime: new Date(),
|
|
681
787
|
role: MemberRole.Viewer,
|
|
682
|
-
url:
|
|
788
|
+
url: 'url',
|
|
683
789
|
numberOfInitializedDownloads: 0,
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
apiService.getShareInvitations = jest.fn().mockResolvedValue([
|
|
687
|
-
|
|
688
|
-
]);
|
|
689
|
-
apiService.getShareExternalInvitations = jest.fn().mockResolvedValue([
|
|
690
|
-
externalInvitation,
|
|
691
|
-
]);
|
|
692
|
-
apiService.getShareMembers = jest.fn().mockResolvedValue([
|
|
693
|
-
member,
|
|
694
|
-
]);
|
|
790
|
+
};
|
|
791
|
+
|
|
792
|
+
apiService.getShareInvitations = jest.fn().mockResolvedValue([invitation]);
|
|
793
|
+
apiService.getShareExternalInvitations = jest.fn().mockResolvedValue([externalInvitation]);
|
|
794
|
+
apiService.getShareMembers = jest.fn().mockResolvedValue([member]);
|
|
695
795
|
apiService.getPublicLink = jest.fn().mockResolvedValue(publicLink);
|
|
696
796
|
});
|
|
697
797
|
|
|
698
|
-
it(
|
|
699
|
-
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: [
|
|
798
|
+
it('should delete invitation', async () => {
|
|
799
|
+
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: ['internal-email'] });
|
|
700
800
|
|
|
701
801
|
expect(sharingInfo).toEqual({
|
|
702
802
|
protonInvitations: [],
|
|
@@ -711,8 +811,8 @@ describe("SharingManagement", () => {
|
|
|
711
811
|
expect(apiService.removePublicLink).not.toHaveBeenCalled();
|
|
712
812
|
});
|
|
713
813
|
|
|
714
|
-
it(
|
|
715
|
-
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: [
|
|
814
|
+
it('should delete external invitation', async () => {
|
|
815
|
+
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: ['external-email'] });
|
|
716
816
|
|
|
717
817
|
expect(sharingInfo).toEqual({
|
|
718
818
|
protonInvitations: [invitation],
|
|
@@ -727,8 +827,8 @@ describe("SharingManagement", () => {
|
|
|
727
827
|
expect(apiService.removePublicLink).not.toHaveBeenCalled();
|
|
728
828
|
});
|
|
729
829
|
|
|
730
|
-
it(
|
|
731
|
-
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: [
|
|
830
|
+
it('should remove member', async () => {
|
|
831
|
+
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: ['member-email'] });
|
|
732
832
|
|
|
733
833
|
expect(sharingInfo).toEqual({
|
|
734
834
|
protonInvitations: [invitation],
|
|
@@ -743,8 +843,8 @@ describe("SharingManagement", () => {
|
|
|
743
843
|
expect(apiService.removePublicLink).not.toHaveBeenCalled();
|
|
744
844
|
});
|
|
745
845
|
|
|
746
|
-
it(
|
|
747
|
-
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: [
|
|
846
|
+
it('should be no-op if not shared with email', async () => {
|
|
847
|
+
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { users: ['non-existing-email'] });
|
|
748
848
|
|
|
749
849
|
expect(sharingInfo).toEqual({
|
|
750
850
|
protonInvitations: [invitation],
|
|
@@ -759,8 +859,8 @@ describe("SharingManagement", () => {
|
|
|
759
859
|
expect(apiService.removePublicLink).not.toHaveBeenCalled();
|
|
760
860
|
});
|
|
761
861
|
|
|
762
|
-
it(
|
|
763
|
-
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { publicLink:
|
|
862
|
+
it('should remove public link', async () => {
|
|
863
|
+
const sharingInfo = await sharingManagement.unshareNode(nodeUid, { publicLink: 'remove' });
|
|
764
864
|
|
|
765
865
|
expect(sharingInfo).toEqual({
|
|
766
866
|
protonInvitations: [invitation],
|
|
@@ -775,7 +875,7 @@ describe("SharingManagement", () => {
|
|
|
775
875
|
expect(apiService.removePublicLink).toHaveBeenCalled();
|
|
776
876
|
});
|
|
777
877
|
|
|
778
|
-
it(
|
|
878
|
+
it('should remove share if all is removed', async () => {
|
|
779
879
|
const sharingInfo = await sharingManagement.unshareNode(nodeUid);
|
|
780
880
|
|
|
781
881
|
expect(sharingInfo).toEqual(undefined);
|
|
@@ -787,10 +887,10 @@ describe("SharingManagement", () => {
|
|
|
787
887
|
expect(nodesService.notifyNodeChanged).toHaveBeenCalled();
|
|
788
888
|
});
|
|
789
889
|
|
|
790
|
-
it(
|
|
890
|
+
it('should remove share if everything is manually removed', async () => {
|
|
791
891
|
const sharingInfo = await sharingManagement.unshareNode(nodeUid, {
|
|
792
|
-
users: [
|
|
793
|
-
publicLink:
|
|
892
|
+
users: ['internal-email', 'external-email', 'member-email'],
|
|
893
|
+
publicLink: 'remove',
|
|
794
894
|
});
|
|
795
895
|
|
|
796
896
|
expect(sharingInfo).toEqual(undefined);
|
|
@@ -802,20 +902,20 @@ describe("SharingManagement", () => {
|
|
|
802
902
|
});
|
|
803
903
|
});
|
|
804
904
|
|
|
805
|
-
describe(
|
|
806
|
-
const nodeUid =
|
|
905
|
+
describe('resendInvitationEmail', () => {
|
|
906
|
+
const nodeUid = 'volumeId~nodeUid';
|
|
807
907
|
|
|
808
908
|
const invitation: ProtonInvitation = {
|
|
809
|
-
uid:
|
|
810
|
-
addedByEmail: resultOk(
|
|
811
|
-
inviteeEmail:
|
|
909
|
+
uid: 'invitation',
|
|
910
|
+
addedByEmail: resultOk('added-email'),
|
|
911
|
+
inviteeEmail: 'internal-email',
|
|
812
912
|
role: MemberRole.Viewer,
|
|
813
913
|
invitationTime: new Date(),
|
|
814
914
|
};
|
|
815
915
|
const externalInvitation: NonProtonInvitation = {
|
|
816
|
-
uid:
|
|
817
|
-
addedByEmail: resultOk(
|
|
818
|
-
inviteeEmail:
|
|
916
|
+
uid: 'external-invitation',
|
|
917
|
+
addedByEmail: resultOk('added-email'),
|
|
918
|
+
inviteeEmail: 'external-email',
|
|
819
919
|
role: MemberRole.Viewer,
|
|
820
920
|
invitationTime: new Date(),
|
|
821
921
|
state: NonProtonInvitationState.Pending,
|
|
@@ -828,35 +928,35 @@ describe("SharingManagement", () => {
|
|
|
828
928
|
apiService.getPublicLink = jest.fn().mockResolvedValue(undefined);
|
|
829
929
|
});
|
|
830
930
|
|
|
831
|
-
it(
|
|
931
|
+
it('should resend email for proton invitation', async () => {
|
|
832
932
|
await sharingManagement.resendInvitationEmail(nodeUid, invitation.uid);
|
|
833
933
|
|
|
834
934
|
expect(apiService.resendInvitationEmail).toHaveBeenCalledWith(invitation.uid);
|
|
835
935
|
expect(apiService.resendExternalInvitationEmail).not.toHaveBeenCalled();
|
|
836
936
|
});
|
|
837
937
|
|
|
838
|
-
it(
|
|
938
|
+
it('should resend email for external invitation', async () => {
|
|
839
939
|
await sharingManagement.resendInvitationEmail(nodeUid, externalInvitation.uid);
|
|
840
940
|
|
|
841
941
|
expect(apiService.resendExternalInvitationEmail).toHaveBeenCalledWith(externalInvitation.uid);
|
|
842
942
|
expect(apiService.resendInvitationEmail).not.toHaveBeenCalled();
|
|
843
943
|
});
|
|
844
944
|
|
|
845
|
-
it(
|
|
945
|
+
it('should throw error when no sharing found for node', async () => {
|
|
846
946
|
nodesService.getNode = jest.fn().mockResolvedValue({ nodeUid, shareId: undefined });
|
|
847
947
|
|
|
848
|
-
await expect(
|
|
849
|
-
|
|
850
|
-
)
|
|
948
|
+
await expect(sharingManagement.resendInvitationEmail(nodeUid, invitation.uid)).rejects.toThrow(
|
|
949
|
+
'Node is not shared',
|
|
950
|
+
);
|
|
851
951
|
|
|
852
952
|
expect(apiService.resendInvitationEmail).not.toHaveBeenCalled();
|
|
853
953
|
expect(apiService.resendExternalInvitationEmail).not.toHaveBeenCalled();
|
|
854
954
|
});
|
|
855
955
|
|
|
856
|
-
it(
|
|
857
|
-
await expect(
|
|
858
|
-
|
|
859
|
-
)
|
|
956
|
+
it('should log when no invitation found', async () => {
|
|
957
|
+
await expect(sharingManagement.resendInvitationEmail(nodeUid, 'non-existent-uid')).rejects.toThrow(
|
|
958
|
+
'Invitation not found',
|
|
959
|
+
);
|
|
860
960
|
|
|
861
961
|
expect(apiService.resendInvitationEmail).not.toHaveBeenCalled();
|
|
862
962
|
expect(apiService.resendExternalInvitationEmail).not.toHaveBeenCalled();
|