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