diff --git a/package-lock.json b/package-lock.json index 43d614a..c5ead7f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,6 +21,7 @@ "@types/node": "^18.6.5", "@types/react": "^18.0.17", "@types/react-dom": "^18.0.6", + "block-iterator": "^1.1.1", "buffer": "^6.0.3", "classnames": "^2.3.1", "detectincognitojs": "^1.1.2", @@ -47,7 +48,7 @@ "typescript": "^4.7.4", "uuid": "^8.3.2", "web-vitals": "^2.1.4", - "webtorrent": "^1.9.4", + "webtorrent": "^1.9.7", "wormhole-crypto": "^0.3.1" }, "devDependencies": { @@ -7518,11 +7519,6 @@ "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz", "integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==" }, - "node_modules/bep53-range": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz", - "integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ==" - }, "node_modules/bfj": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", @@ -7591,9 +7587,9 @@ } }, "node_modules/bittorrent-dht": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.6.tgz", - "integrity": "sha512-Odmfmo36/vr0E4PWicans0fesjCfRib2daGaYfB8WHljPTO/U2820EFOA9HBhzdzekGBhBHlSPVi6Jf9vu7/yQ==", + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.7.tgz", + "integrity": "sha512-o6elCANGteECXz82LFqG1Ov2fG4uNzfUU7pBMx9ixxKUh99ZXNrhbiNLRNN2F2vBnqKSN7SHlUW4LJ5Z2u1eKw==", "funding": [ { "type": "github", @@ -7792,9 +7788,9 @@ } }, "node_modules/block-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.0.1.tgz", - "integrity": "sha512-ral9Gh8BXqVkh4lnhLLL5QJ67+VMOBNzsHJZX4n+Pwer9bzcSM2ZOjTLMErkWWETvnis+ZP1a6EULebjEg3bTA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.1.1.tgz", + "integrity": "sha512-DrjdVWZemVO4iBf4tiOXjUrY5cNesjzy0t7sIiu2rdl8cOCHRxAgKjSJFc3vBZYYMMmshUAxajl8QQh/uxXTKQ==" }, "node_modules/block-stream2": { "version": "2.1.0", @@ -9167,44 +9163,6 @@ "sha.js": "^2.4.8" } }, - "node_modules/create-torrent": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz", - "integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "bencode": "^2.0.3", - "block-iterator": "^1.0.1", - "fast-readable-async-iterator": "^1.1.1", - "is-file": "^1.0.0", - "join-async-iterator": "^1.1.1", - "junk": "^3.1.0", - "minimist": "^1.2.7", - "piece-length": "^2.0.1", - "queue-microtask": "^1.2.3", - "run-parallel": "^1.2.0", - "simple-sha1": "^3.1.0" - }, - "bin": { - "create-torrent": "bin/cmd.js" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -12395,17 +12353,6 @@ "node": ">=8.0.0" } }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -17857,29 +17804,6 @@ "sourcemap-codec": "^1.4.8" } }, - "node_modules/magnet-uri": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz", - "integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "bep53-range": "^1.1.0", - "thirty-two": "^1.0.2" - } - }, "node_modules/make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -19909,37 +19833,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-torrent": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz", - "integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "bencode": "^2.0.2", - "blob-to-buffer": "^1.2.9", - "get-stdin": "^8.0.0", - "magnet-uri": "^6.2.0", - "queue-microtask": "^1.2.3", - "simple-get": "^4.0.1", - "simple-sha1": "^3.1.0" - }, - "bin": { - "parse-torrent": "bin/cmd.js" - } - }, "node_modules/parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -24241,12 +24134,12 @@ ] }, "node_modules/streamx": { - "version": "2.12.5", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.12.5.tgz", - "integrity": "sha512-Y+nkFw57Z5JHT3zLlqFm3GccOy2FeYdUrrqita6Dd8kr/8enPn9GKa8IYf3/DmEKfZl/E2sWoSKUnd4qhonrgg==", + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz", + "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==", "dependencies": { - "fast-fifo": "^1.0.0", - "queue-tick": "^1.0.0" + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" } }, "node_modules/string_decoder": { @@ -24917,9 +24810,9 @@ } }, "node_modules/torrent-discovery": { - "version": "9.4.14", - "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.14.tgz", - "integrity": "sha512-IyzlrHctvqqKtN8Y2BMxNL3d2FLazs6pC2yzKOHJlXWYUFkLpZhZSaSZcAkfmZXgdjwq59N2umr1przsRDMzkA==", + "version": "9.4.15", + "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.15.tgz", + "integrity": "sha512-71nx+TpLaF27mbsSj/tZTr588Dfk7XVzx+Rf1+nrxfXqe8qn5dIlRhgA+yY4cg8Ib69vWwkKFhAzbRqg8z42aw==", "funding": [ { "type": "github", @@ -24935,7 +24828,7 @@ } ], "dependencies": { - "bittorrent-dht": "^10.0.6", + "bittorrent-dht": "^10.0.7", "bittorrent-lsd": "^1.1.1", "bittorrent-tracker": "^9.19.0", "debug": "^4.3.4", @@ -26152,9 +26045,9 @@ } }, "node_modules/webtorrent": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.4.tgz", - "integrity": "sha512-dW/7Cj/fRiJe97Vac071VhbfbiDSF6iAW1wwbs47uArOBbRSAgDRTem70M7ONF3IwRC/mu1+bTSwv+ojxJ+2/A==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.7.tgz", + "integrity": "sha512-N+hRuVctWviTAYem/sI6tuFP2J/Rn3/ETEh++7GnJv6Oro49kDjcPuz1W6s+vfS65xKr3Eh4HMuxf3hH82LGfg==", "funding": [ { "type": "github", @@ -26173,7 +26066,7 @@ "@webtorrent/http-node": "^1.3.0", "addr-to-ip-port": "^1.5.4", "bitfield": "^4.1.0", - "bittorrent-dht": "^10.0.6", + "bittorrent-dht": "^10.0.7", "bittorrent-protocol": "^3.5.5", "cache-chunk-store": "^3.2.2", "chrome-net": "^3.3.4", @@ -26209,7 +26102,7 @@ "stream-with-known-length-to-buffer": "^1.0.4", "streamx": "^2.12.5", "throughput": "^1.0.1", - "torrent-discovery": "^9.4.14", + "torrent-discovery": "^9.4.15", "torrent-piece": "^2.0.1", "unordered-array-remove": "^1.0.2", "ut_metadata": "^3.5.2", @@ -26222,6 +26115,83 @@ "utp-native": "^2.5.3" } }, + "node_modules/webtorrent/node_modules/bep53-range": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz", + "integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ==" + }, + "node_modules/webtorrent/node_modules/create-torrent": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz", + "integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^2.0.3", + "block-iterator": "^1.0.1", + "fast-readable-async-iterator": "^1.1.1", + "is-file": "^1.0.0", + "join-async-iterator": "^1.1.1", + "junk": "^3.1.0", + "minimist": "^1.2.7", + "piece-length": "^2.0.1", + "queue-microtask": "^1.2.3", + "run-parallel": "^1.2.0", + "simple-sha1": "^3.1.0" + }, + "bin": { + "create-torrent": "bin/cmd.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/webtorrent/node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/webtorrent/node_modules/magnet-uri": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz", + "integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bep53-range": "^1.1.0", + "thirty-two": "^1.0.2" + } + }, "node_modules/webtorrent/node_modules/mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", @@ -26233,6 +26203,37 @@ "node": ">=10.0.0" } }, + "node_modules/webtorrent/node_modules/parse-torrent": { + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz", + "integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "bencode": "^2.0.2", + "blob-to-buffer": "^1.2.9", + "get-stdin": "^8.0.0", + "magnet-uri": "^6.2.0", + "queue-microtask": "^1.2.3", + "simple-get": "^4.0.1", + "simple-sha1": "^3.1.0" + }, + "bin": { + "parse-torrent": "bin/cmd.js" + } + }, "node_modules/whatwg-encoding": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", @@ -32342,11 +32343,6 @@ "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.3.tgz", "integrity": "sha512-D/vrAD4dLVX23NalHwb8dSvsUsxeRPO8Y7ToKA015JQYq69MLDOMkC0uGZYA/MPpltLO8rt8eqFC2j8DxjTZ/w==" }, - "bep53-range": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz", - "integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ==" - }, "bfj": { "version": "7.0.2", "resolved": "https://registry.npmjs.org/bfj/-/bfj-7.0.2.tgz", @@ -32397,9 +32393,9 @@ "integrity": "sha512-6cEDG3K+PK9f+B7WyhWYjp09bqSa+uaAaecVA7Y5giFixyVe1s6HKGnvOqYNR4Mi4fBMjfDPLBpHkKvzzgP7kg==" }, "bittorrent-dht": { - "version": "10.0.6", - "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.6.tgz", - "integrity": "sha512-Odmfmo36/vr0E4PWicans0fesjCfRib2daGaYfB8WHljPTO/U2820EFOA9HBhzdzekGBhBHlSPVi6Jf9vu7/yQ==", + "version": "10.0.7", + "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-10.0.7.tgz", + "integrity": "sha512-o6elCANGteECXz82LFqG1Ov2fG4uNzfUU7pBMx9ixxKUh99ZXNrhbiNLRNN2F2vBnqKSN7SHlUW4LJ5Z2u1eKw==", "requires": { "bencode": "^2.0.3", "debug": "^4.3.4", @@ -32505,9 +32501,9 @@ } }, "block-iterator": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.0.1.tgz", - "integrity": "sha512-ral9Gh8BXqVkh4lnhLLL5QJ67+VMOBNzsHJZX4n+Pwer9bzcSM2ZOjTLMErkWWETvnis+ZP1a6EULebjEg3bTA==" + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/block-iterator/-/block-iterator-1.1.1.tgz", + "integrity": "sha512-DrjdVWZemVO4iBf4tiOXjUrY5cNesjzy0t7sIiu2rdl8cOCHRxAgKjSJFc3vBZYYMMmshUAxajl8QQh/uxXTKQ==" }, "block-stream2": { "version": "2.1.0", @@ -33498,24 +33494,6 @@ "sha.js": "^2.4.8" } }, - "create-torrent": { - "version": "5.0.9", - "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz", - "integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==", - "requires": { - "bencode": "^2.0.3", - "block-iterator": "^1.0.1", - "fast-readable-async-iterator": "^1.1.1", - "is-file": "^1.0.0", - "join-async-iterator": "^1.1.1", - "junk": "^3.1.0", - "minimist": "^1.2.7", - "piece-length": "^2.0.1", - "queue-microtask": "^1.2.3", - "run-parallel": "^1.2.0", - "simple-sha1": "^3.1.0" - } - }, "cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -35868,11 +35846,6 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==" }, - "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==" - }, "get-stream": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", @@ -40104,15 +40077,6 @@ "sourcemap-codec": "^1.4.8" } }, - "magnet-uri": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz", - "integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==", - "requires": { - "bep53-range": "^1.1.0", - "thirty-two": "^1.0.2" - } - }, "make-dir": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", @@ -41507,20 +41471,6 @@ "lines-and-columns": "^1.1.6" } }, - "parse-torrent": { - "version": "9.1.5", - "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz", - "integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==", - "requires": { - "bencode": "^2.0.2", - "blob-to-buffer": "^1.2.9", - "get-stdin": "^8.0.0", - "magnet-uri": "^6.2.0", - "queue-microtask": "^1.2.3", - "simple-get": "^4.0.1", - "simple-sha1": "^3.1.0" - } - }, "parse5": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", @@ -44484,12 +44434,12 @@ "integrity": "sha512-LK4e7TfCV8HzuM0PKXuVUfKyCB1FtT9L0EGxsFk5Up8njj0bXK8pJM9+Wq2Nya7/jslmCQwRK39LFm55h7NBTw==" }, "streamx": { - "version": "2.12.5", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.12.5.tgz", - "integrity": "sha512-Y+nkFw57Z5JHT3zLlqFm3GccOy2FeYdUrrqita6Dd8kr/8enPn9GKa8IYf3/DmEKfZl/E2sWoSKUnd4qhonrgg==", + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz", + "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==", "requires": { - "fast-fifo": "^1.0.0", - "queue-tick": "^1.0.0" + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" } }, "string_decoder": { @@ -44997,11 +44947,11 @@ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" }, "torrent-discovery": { - "version": "9.4.14", - "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.14.tgz", - "integrity": "sha512-IyzlrHctvqqKtN8Y2BMxNL3d2FLazs6pC2yzKOHJlXWYUFkLpZhZSaSZcAkfmZXgdjwq59N2umr1przsRDMzkA==", + "version": "9.4.15", + "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-9.4.15.tgz", + "integrity": "sha512-71nx+TpLaF27mbsSj/tZTr588Dfk7XVzx+Rf1+nrxfXqe8qn5dIlRhgA+yY4cg8Ib69vWwkKFhAzbRqg8z42aw==", "requires": { - "bittorrent-dht": "^10.0.6", + "bittorrent-dht": "^10.0.7", "bittorrent-lsd": "^1.1.1", "bittorrent-tracker": "^9.19.0", "debug": "^4.3.4", @@ -45874,14 +45824,14 @@ "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==" }, "webtorrent": { - "version": "1.9.4", - "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.4.tgz", - "integrity": "sha512-dW/7Cj/fRiJe97Vac071VhbfbiDSF6iAW1wwbs47uArOBbRSAgDRTem70M7ONF3IwRC/mu1+bTSwv+ojxJ+2/A==", + "version": "1.9.7", + "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-1.9.7.tgz", + "integrity": "sha512-N+hRuVctWviTAYem/sI6tuFP2J/Rn3/ETEh++7GnJv6Oro49kDjcPuz1W6s+vfS65xKr3Eh4HMuxf3hH82LGfg==", "requires": { "@webtorrent/http-node": "^1.3.0", "addr-to-ip-port": "^1.5.4", "bitfield": "^4.1.0", - "bittorrent-dht": "^10.0.6", + "bittorrent-dht": "^10.0.7", "bittorrent-protocol": "^3.5.5", "cache-chunk-store": "^3.2.2", "chrome-net": "^3.3.4", @@ -45917,7 +45867,7 @@ "stream-with-known-length-to-buffer": "^1.0.4", "streamx": "^2.12.5", "throughput": "^1.0.1", - "torrent-discovery": "^9.4.14", + "torrent-discovery": "^9.4.15", "torrent-piece": "^2.0.1", "unordered-array-remove": "^1.0.2", "ut_metadata": "^3.5.2", @@ -45925,10 +45875,61 @@ "utp-native": "^2.5.3" }, "dependencies": { + "bep53-range": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/bep53-range/-/bep53-range-1.1.1.tgz", + "integrity": "sha512-ct6s33iiwRCUPp9KXnJ4QMWDgHIgaw36caK/5XEQ9L8dCzSQlJt1Vk6VmHh1VD4AlGCAI4C2zmtfItifBBPrhQ==" + }, + "create-torrent": { + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-5.0.9.tgz", + "integrity": "sha512-WQ/bMe+aCBSa5EonIkgw7CTM/1JnJDQuLJhA78omSWvuEbXDwaUy0rG3a+IYt+EiO+rdTLxdsBwrsn/wfWOMQA==", + "requires": { + "bencode": "^2.0.3", + "block-iterator": "^1.0.1", + "fast-readable-async-iterator": "^1.1.1", + "is-file": "^1.0.0", + "join-async-iterator": "^1.1.1", + "junk": "^3.1.0", + "minimist": "^1.2.7", + "piece-length": "^2.0.1", + "queue-microtask": "^1.2.3", + "run-parallel": "^1.2.0", + "simple-sha1": "^3.1.0" + } + }, + "get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==" + }, + "magnet-uri": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-6.2.0.tgz", + "integrity": "sha512-O9AgdDwT771fnUj0giPYu/rACpz8173y8UXCSOdLITjOVfBenZ9H9q3FqQmveK+ORUMuD+BkKNSZP8C3+IMAKQ==", + "requires": { + "bep53-range": "^1.1.0", + "thirty-two": "^1.0.2" + } + }, "mime": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==" + }, + "parse-torrent": { + "version": "9.1.5", + "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-9.1.5.tgz", + "integrity": "sha512-K8FXRwTOaZMI0/xuv0dpng1MVHZRtMJ0jRWBJ3qZWVNTrC1MzWUxm9QwaXDz/2qPhV2XC4UIHI92IGHwseAwaA==", + "requires": { + "bencode": "^2.0.2", + "blob-to-buffer": "^1.2.9", + "get-stdin": "^8.0.0", + "magnet-uri": "^6.2.0", + "queue-microtask": "^1.2.3", + "simple-get": "^4.0.1", + "simple-sha1": "^3.1.0" + } } } }, diff --git a/package.json b/package.json index dda612d..2ad6b27 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "@types/node": "^18.6.5", "@types/react": "^18.0.17", "@types/react-dom": "^18.0.6", + "block-iterator": "^1.1.1", "buffer": "^6.0.3", "classnames": "^2.3.1", "detectincognitojs": "^1.1.2", @@ -43,7 +44,7 @@ "typescript": "^4.7.4", "uuid": "^8.3.2", "web-vitals": "^2.1.4", - "webtorrent": "^1.9.4", + "webtorrent": "^1.9.7", "wormhole-crypto": "^0.3.1" }, "scripts": { diff --git a/src/services/FileTransfer/FileTransfer.ts b/src/services/FileTransfer/FileTransfer.ts index b31c803..df8afb3 100644 --- a/src/services/FileTransfer/FileTransfer.ts +++ b/src/services/FileTransfer/FileTransfer.ts @@ -1,24 +1,22 @@ import WebTorrent, { Torrent, TorrentFile } from 'webtorrent' +// @ts-ignore import streamSaver from 'streamsaver' // @ts-ignore -import { Keychain, plaintextSize } from 'wormhole-crypto' +import { Keychain, plaintextSize, encryptedSize } from 'wormhole-crypto' // @ts-ignore import idbChunkStore from 'idb-chunk-store' import { detectIncognito } from 'detectincognitojs' import { trackerUrls } from 'config/trackerUrls' import { streamSaverUrl } from 'config/streamSaverUrl' +// @ts-ignore +import blockIterator from 'block-iterator' -import { ReadableWebToNodeStream } from 'readable-web-to-node-stream' // @ts-ignore import nodeToWebStream from 'readable-stream-node-to-web' streamSaver.mitm = streamSaverUrl -interface NamedReadableWebToNodeStream extends NodeJS.ReadableStream { - name?: string -} - const getKeychain = (password: string) => { const encoder = new TextEncoder() const keyLength = 16 @@ -64,11 +62,12 @@ export class FileTransfer { async getDecryptedFileReadStream(file: TorrentFile, password: string) { const keychain = getKeychain(password) - const readStream: ReadableStream = await keychain.decryptStream( - nodeToWebStream(file.createReadStream()) + + const decryptedStream: ReadableStream = await keychain.decryptStream( + new nodeToWebStream(file.createReadStream()) ) - return readStream + return decryptedStream } async download( @@ -127,27 +126,101 @@ export class FileTransfer { const filesToSeed: File[] = files instanceof FileList ? Array.from(files) : files + const pieceLength = 16 * 1024 + + const fileToEncryptedStoreMap: Map ReadableStream> = + new Map() + + const tempStores: idbChunkStore[] = [] + + for (const file of filesToSeed) { + const tempStore = new idbChunkStore(pieceLength, { + name: `${file.name} - temp`, + length: encryptedSize(file.size), + }) + + tempStores.push(tempStore) + + const encryptedStream = await getKeychain(password).encryptStream( + file.stream() + ) + + const blockStream = blockIterator(encryptedStream, pieceLength, { + zeroPadding: false, + }) + + let numberOfChunks = 0 + let i = 0 + for await (const chunk of blockStream) { + // eslint-disable-next-line no-loop-func + await new Promise((resolve, reject) => { + tempStore.put(i, chunk, (err?: Error) => { + if (err) return reject(err) + + resolve() + }) + }) + + i++ + numberOfChunks = i + } + + const streamFactory = () => { + let i = 0 + + const readableStream = new ReadableStream({ + async pull(controller) { + const buffer = await new Promise(resolve => { + tempStore.get( + i, + undefined, + (_err: Error | null, buffer: Buffer) => { + resolve(buffer) + } + ) + }) + + i++ + + const done = i > numberOfChunks + + if (done) { + controller.close() + } else { + controller.enqueue(buffer) + } + }, + }) + + return readableStream + } + + fileToEncryptedStoreMap.set(file, streamFactory) + } + const encryptedFiles = await Promise.all( filesToSeed.map(async file => { - const encryptedStream = await getKeychain(password).encryptStream( - file.stream() + const streamFactory = fileToEncryptedStoreMap.get(file) + + if (!streamFactory) { + throw new Error(`streamFactory is undefined`) + } + + const encryptedFile = Object.setPrototypeOf( + { + ...file, + name: file.name, + size: encryptedSize(file.size), + stream: () => streamFactory(), + }, + File.prototype ) - // WebTorrent only accepts Node-style ReadableStreams - const nodeStream: NamedReadableWebToNodeStream = - new ReadableWebToNodeStream( - encryptedStream - // ReadableWebToNodeStream is the same as NodeJS.ReadableStream. - // The library's typing is wrong. - ) as any as NodeJS.ReadableStream - - nodeStream.name = file.name - - return nodeStream + return encryptedFile }) ) - const torrent = await new Promise(res => { + const offer = await new Promise(res => { this.webTorrentClient.seed( encryptedFiles, { @@ -164,8 +237,16 @@ export class FileTransfer { ) }) - const { magnetURI } = torrent - this.torrents[magnetURI] = torrent + for (const store of tempStores) { + await new Promise(resolve => { + store.destroy(() => { + resolve() + }) + }) + } + + const { magnetURI } = offer + this.torrents[magnetURI] = offer return magnetURI }