From 21cc9c3d8ad142679a2bba7ba053f8bb8a154bae Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Feb 2023 10:23:29 +0000 Subject: [PATCH 01/24] Update jest monorepo to v29.4.3 (#3169) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 917 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 535 insertions(+), 382 deletions(-) diff --git a/yarn.lock b/yarn.lock index 319e90431f4..5feb445c29c 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27,7 +27,7 @@ dependencies: tunnel "^0.0.6" -"@ampproject/remapping@^2.1.0": +"@ampproject/remapping@^2.1.0", "@ampproject/remapping@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== @@ -64,11 +64,11 @@ integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== "@babel/compat-data@^7.20.5": - version "7.20.14" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.14.tgz#4106fc8b755f3e3ee0a0a7c27dde5de1d2b2baf8" - integrity sha512-0YpKHD6ImkWMEINCyDAD0HLLUH/lPCefG8ld9it8DJB2wnApraKuhgYTvTY1z7UFIfBTGy5LwncZ+5HWWGbhFw== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.0.tgz#c241dc454e5b5917e40d37e525e2f4530c399298" + integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g== -"@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": +"@babel/core@^7.0.0", "@babel/core@^7.12.10", "@babel/core@^7.7.5": version "7.20.12" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== @@ -89,6 +89,27 @@ json5 "^2.2.2" semver "^6.3.0" +"@babel/core@^7.11.6", "@babel/core@^7.12.3": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.0.tgz#1341aefdcc14ccc7553fcc688dd8986a2daffc13" + integrity sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA== + dependencies: + "@ampproject/remapping" "^2.2.0" + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.21.0" + "@babel/helper-compilation-targets" "^7.20.7" + "@babel/helper-module-transforms" "^7.21.0" + "@babel/helpers" "^7.21.0" + "@babel/parser" "^7.21.0" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.0" + "@babel/types" "^7.21.0" + convert-source-map "^1.7.0" + debug "^4.1.0" + gensync "^1.0.0-beta.2" + json5 "^2.2.2" + semver "^6.3.0" + "@babel/eslint-parser@^7.12.10": version "7.19.1" resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.19.1.tgz#4f68f6b0825489e00a24b41b6a1ae35414ecd2f4" @@ -114,13 +135,14 @@ "@jridgewell/gen-mapping" "^0.3.2" jsesc "^2.5.1" -"@babel/generator@^7.20.7", "@babel/generator@^7.7.2": - version "7.20.14" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.20.14.tgz#9fa772c9f86a46c6ac9b321039400712b96f64ce" - integrity sha512-AEmuXHdcD3A52HHXxaTmYlb8q/xMEhoRP67B3T4Oq7lbmSoqroMZzjnGj3+i1io3pdnF8iBYVu4Ilj+c4hBxYg== +"@babel/generator@^7.20.7", "@babel/generator@^7.21.0", "@babel/generator@^7.7.2": + version "7.21.1" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.1.tgz#951cc626057bc0af2c35cd23e9c64d384dea83dd" + integrity sha512-1lT45bAYlQhFn/BHivJs43AiW2rg3/UbLyShGfF3C0KmHvO5fSghWd5kBJy30kpRRucGzXStvnnCFniCR2kXAA== dependencies: - "@babel/types" "^7.20.7" + "@babel/types" "^7.21.0" "@jridgewell/gen-mapping" "^0.3.2" + "@jridgewell/trace-mapping" "^0.3.17" jsesc "^2.5.1" "@babel/helper-annotate-as-pure@^7.18.6": @@ -194,7 +216,7 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-function-name@^7.18.9", "@babel/helper-function-name@^7.19.0": +"@babel/helper-function-name@^7.18.9": version "7.19.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz#941574ed5390682e872e52d3f38ce9d1bef4648c" integrity sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w== @@ -202,6 +224,14 @@ "@babel/template" "^7.18.10" "@babel/types" "^7.19.0" +"@babel/helper-function-name@^7.19.0", "@babel/helper-function-name@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4" + integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg== + dependencies: + "@babel/template" "^7.20.7" + "@babel/types" "^7.21.0" + "@babel/helper-hoist-variables@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678" @@ -223,7 +253,7 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-module-transforms@^7.18.6", "@babel/helper-module-transforms@^7.20.11": +"@babel/helper-module-transforms@^7.18.6": version "7.20.11" resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.20.11.tgz#df4c7af713c557938c50ea3ad0117a7944b2f1b0" integrity sha512-uRy78kN4psmji1s2QtbtcCSaj/LILFDp0f/ymhpQH5QY3nljUZCaNWz9X1dEj/8MBdBEFECs7yRhKn8i7NjZgg== @@ -237,6 +267,20 @@ "@babel/traverse" "^7.20.10" "@babel/types" "^7.20.7" +"@babel/helper-module-transforms@^7.20.11", "@babel/helper-module-transforms@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.0.tgz#89a8f86ad748870e3d024e470b2e8405e869db67" + integrity sha512-eD/JQ21IG2i1FraJnTMbUarAUkA7G988ofehG5MDCRXaUU91rEBJuCeSoou2Sk1y4RbLYXzqEg1QLwEmRU4qcQ== + dependencies: + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-module-imports" "^7.18.6" + "@babel/helper-simple-access" "^7.20.2" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-validator-identifier" "^7.19.1" + "@babel/template" "^7.20.7" + "@babel/traverse" "^7.21.0" + "@babel/types" "^7.21.0" + "@babel/helper-optimise-call-expression@^7.18.6": version "7.18.6" resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.18.6.tgz#9369aa943ee7da47edab2cb4e838acf09d290ffe" @@ -303,9 +347,9 @@ integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== "@babel/helper-validator-option@^7.18.6": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz#bf0d2b5a509b1f336099e4ff36e1a63aa5db4db8" - integrity sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" + integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== "@babel/helper-wrap-function@^7.18.9": version "7.20.5" @@ -317,14 +361,14 @@ "@babel/traverse" "^7.20.5" "@babel/types" "^7.20.5" -"@babel/helpers@^7.20.7": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.20.13.tgz#e3cb731fb70dc5337134cadc24cbbad31cc87ad2" - integrity sha512-nzJ0DWCL3gB5RCXbUO3KIMMsBY2Eqbx8mBpKGE/02PgyRQFcPQLbkQ1vyy596mZLaP+dAfD+R4ckASzNVmW3jg== +"@babel/helpers@^7.20.7", "@babel/helpers@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" + integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== dependencies: "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.13" - "@babel/types" "^7.20.7" + "@babel/traverse" "^7.21.0" + "@babel/types" "^7.21.0" "@babel/highlight@^7.18.6": version "7.18.6" @@ -335,10 +379,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.13", "@babel/parser@^7.20.7": - version "7.20.15" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.20.15.tgz#eec9f36d8eaf0948bb88c87a46784b5ee9fd0c89" - integrity sha512-DI4a1oZuf8wC+oAJA9RW6ga3Zbe8RZFt7kD9i4qAspz3I/yHet1VvC3DiSy/fsUvv5pvJuNPh0LPOdCcqinDPg== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.13", "@babel/parser@^7.20.7", "@babel/parser@^7.21.0": + version "7.21.1" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.1.tgz#a8f81ee2fe872af23faea4b17a08fcc869de7bcc" + integrity sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg== "@babel/parser@^7.2.3": version "7.20.7" @@ -1039,7 +1083,23 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.20.13", "@babel/traverse@^7.20.7", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.21.0", "@babel/traverse@^7.7.2": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.0.tgz#0e1807abd5db98e6a19c204b80ed1e3f5bca0edc" + integrity sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA== + dependencies: + "@babel/code-frame" "^7.18.6" + "@babel/generator" "^7.21.0" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-hoist-variables" "^7.18.6" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/parser" "^7.21.0" + "@babel/types" "^7.21.0" + debug "^4.1.0" + globals "^11.1.0" + +"@babel/traverse@^7.20.7": version "7.20.13" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473" integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ== @@ -1055,7 +1115,16 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.18.9", "@babel/types@^7.19.0", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.5", "@babel/types@^7.20.7", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.0.tgz#1da00d89c2f18b226c9207d96edbeb79316a1819" + integrity sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow== + dependencies: + "@babel/helper-string-parser" "^7.19.4" + "@babel/helper-validator-identifier" "^7.19.1" + to-fast-properties "^2.0.0" + +"@babel/types@^7.18.9", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.4.4": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== @@ -1144,61 +1213,61 @@ resolved "https://registry.yarnpkg.com/@istanbuljs/schema/-/schema-0.1.3.tgz#e45e384e4b8ec16bce2fd903af78450f6bf7ec98" integrity sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA== -"@jest/console@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.2.tgz#f78374905c2454764152904a344a2d5226b0ef09" - integrity sha512-0I/rEJwMpV9iwi9cDEnT71a5nNGK9lj8Z4+1pRAU2x/thVXCDnaTGrvxyK+cAqZTFVFCiR+hfVrP4l2m+dCmQg== +"@jest/console@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/console/-/console-29.4.3.tgz#1f25a99f7f860e4c46423b5b1038262466fadde1" + integrity sha512-W/o/34+wQuXlgqlPYTansOSiBnuxrTv61dEVkA6HNmpcgHLUjfaUbdqt6oVvOzaawwo9IdW9QOtMgQ1ScSZC4A== dependencies: - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" "@types/node" "*" chalk "^4.0.0" - jest-message-util "^29.4.2" - jest-util "^29.4.2" + jest-message-util "^29.4.3" + jest-util "^29.4.3" slash "^3.0.0" -"@jest/core@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.2.tgz#6e999b67bdc2df9d96ba9b142465bda71ee472c2" - integrity sha512-KGuoQah0P3vGNlaS/l9/wQENZGNKGoWb+OPxh3gz+YzG7/XExvYu34MzikRndQCdM2S0tzExN4+FL37i6gZmCQ== - dependencies: - "@jest/console" "^29.4.2" - "@jest/reporters" "^29.4.2" - "@jest/test-result" "^29.4.2" - "@jest/transform" "^29.4.2" - "@jest/types" "^29.4.2" +"@jest/core@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/core/-/core-29.4.3.tgz#829dd65bffdb490de5b0f69e97de8e3b5eadd94b" + integrity sha512-56QvBq60fS4SPZCuM7T+7scNrkGIe7Mr6PVIXUpu48ouvRaWOFqRPV91eifvFM0ay2HmfswXiGf97NGUN5KofQ== + dependencies: + "@jest/console" "^29.4.3" + "@jest/reporters" "^29.4.3" + "@jest/test-result" "^29.4.3" + "@jest/transform" "^29.4.3" + "@jest/types" "^29.4.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" ci-info "^3.2.0" exit "^0.1.2" graceful-fs "^4.2.9" - jest-changed-files "^29.4.2" - jest-config "^29.4.2" - jest-haste-map "^29.4.2" - jest-message-util "^29.4.2" - jest-regex-util "^29.4.2" - jest-resolve "^29.4.2" - jest-resolve-dependencies "^29.4.2" - jest-runner "^29.4.2" - jest-runtime "^29.4.2" - jest-snapshot "^29.4.2" - jest-util "^29.4.2" - jest-validate "^29.4.2" - jest-watcher "^29.4.2" + jest-changed-files "^29.4.3" + jest-config "^29.4.3" + jest-haste-map "^29.4.3" + jest-message-util "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.4.3" + jest-resolve-dependencies "^29.4.3" + jest-runner "^29.4.3" + jest-runtime "^29.4.3" + jest-snapshot "^29.4.3" + jest-util "^29.4.3" + jest-validate "^29.4.3" + jest-watcher "^29.4.3" micromatch "^4.0.4" - pretty-format "^29.4.2" + pretty-format "^29.4.3" slash "^3.0.0" strip-ansi "^6.0.0" -"@jest/environment@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.2.tgz#ee92c316ee2fbdf0bcd9d2db0ef42d64fea26b56" - integrity sha512-JKs3VUtse0vQfCaFGJRX1bir9yBdtasxziSyu+pIiEllAQOe4oQhdCYIf3+Lx+nGglFktSKToBnRJfD5QKp+NQ== +"@jest/environment@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/environment/-/environment-29.4.3.tgz#9fe2f3169c3b33815dc4bd3960a064a83eba6548" + integrity sha512-dq5S6408IxIa+lr54zeqce+QgI+CJT4nmmA+1yzFgtcsGK8c/EyiUb9XQOgz3BMKrRDfKseeOaxj2eO8LlD3lA== dependencies: - "@jest/fake-timers" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/fake-timers" "^29.4.3" + "@jest/types" "^29.4.3" "@types/node" "*" - jest-mock "^29.4.2" + jest-mock "^29.4.3" "@jest/expect-utils@^28.1.3": version "28.1.3" @@ -1214,53 +1283,53 @@ dependencies: jest-get-type "^29.2.0" -"@jest/expect-utils@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.2.tgz#cd0065dfdd8e8a182aa350cc121db97b5eed7b3f" - integrity sha512-Dd3ilDJpBnqa0GiPN7QrudVs0cczMMHtehSo2CSTjm3zdHx0RcpmhFNVEltuEFeqfLIyWKFI224FsMSQ/nsJQA== +"@jest/expect-utils@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/expect-utils/-/expect-utils-29.4.3.tgz#95ce4df62952f071bcd618225ac7c47eaa81431e" + integrity sha512-/6JWbkxHOP8EoS8jeeTd9dTfc9Uawi+43oLKHfp6zzux3U2hqOOVnV3ai4RpDYHOccL6g+5nrxpoc8DmJxtXVQ== dependencies: - jest-get-type "^29.4.2" + jest-get-type "^29.4.3" -"@jest/expect@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.2.tgz#2d4a6a41b29380957c5094de19259f87f194578b" - integrity sha512-NUAeZVApzyaeLjfWIV/64zXjA2SS+NuUPHpAlO7IwVMGd5Vf9szTl9KEDlxY3B4liwLO31os88tYNHl6cpjtKQ== +"@jest/expect@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/expect/-/expect-29.4.3.tgz#d31a28492e45a6bcd0f204a81f783fe717045c6e" + integrity sha512-iktRU/YsxEtumI9zsPctYUk7ptpC+AVLLk1Ax3AsA4g1C+8OOnKDkIQBDHtD5hA/+VtgMd5AWI5gNlcAlt2vxQ== dependencies: - expect "^29.4.2" - jest-snapshot "^29.4.2" + expect "^29.4.3" + jest-snapshot "^29.4.3" -"@jest/fake-timers@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.2.tgz#af43ee1a5720b987d0348f80df98f2cb17d45cd0" - integrity sha512-Ny1u0Wg6kCsHFWq7A/rW/tMhIedq2siiyHyLpHCmIhP7WmcAmd2cx95P+0xtTZlj5ZbJxIRQi4OPydZZUoiSQQ== +"@jest/fake-timers@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/fake-timers/-/fake-timers-29.4.3.tgz#31e982638c60fa657d310d4b9d24e023064027b0" + integrity sha512-4Hote2MGcCTWSD2gwl0dwbCpBRHhE6olYEuTj8FMowdg3oQWNKr2YuxenPQYZ7+PfqPY1k98wKDU4Z+Hvd4Tiw== dependencies: - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" "@sinonjs/fake-timers" "^10.0.2" "@types/node" "*" - jest-message-util "^29.4.2" - jest-mock "^29.4.2" - jest-util "^29.4.2" + jest-message-util "^29.4.3" + jest-mock "^29.4.3" + jest-util "^29.4.3" -"@jest/globals@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.2.tgz#73f85f5db0e17642258b25fd0b9fc89ddedb50eb" - integrity sha512-zCk70YGPzKnz/I9BNFDPlK+EuJLk21ur/NozVh6JVM86/YYZtZHqxFFQ62O9MWq7uf3vIZnvNA0BzzrtxD9iyg== +"@jest/globals@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/globals/-/globals-29.4.3.tgz#63a2c4200d11bc6d46f12bbe25b07f771fce9279" + integrity sha512-8BQ/5EzfOLG7AaMcDh7yFCbfRLtsc+09E1RQmRBI4D6QQk4m6NSK/MXo+3bJrBN0yU8A2/VIcqhvsOLFmziioA== dependencies: - "@jest/environment" "^29.4.2" - "@jest/expect" "^29.4.2" - "@jest/types" "^29.4.2" - jest-mock "^29.4.2" + "@jest/environment" "^29.4.3" + "@jest/expect" "^29.4.3" + "@jest/types" "^29.4.3" + jest-mock "^29.4.3" -"@jest/reporters@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.2.tgz#6abfa923941daae0acc76a18830ee9e79a22042d" - integrity sha512-10yw6YQe75zCgYcXgEND9kw3UZZH5tJeLzWv4vTk/2mrS1aY50A37F+XT2hPO5OqQFFnUWizXD8k1BMiATNfUw== +"@jest/reporters@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/reporters/-/reporters-29.4.3.tgz#0a68a0c0f20554760cc2e5443177a0018969e353" + integrity sha512-sr2I7BmOjJhyqj9ANC6CTLsL4emMoka7HkQpcoMRlhCbQJjz2zsRzw0BDPiPyEFDXAbxKgGFYuQZiSJ1Y6YoTg== dependencies: "@bcoe/v8-coverage" "^0.2.3" - "@jest/console" "^29.4.2" - "@jest/test-result" "^29.4.2" - "@jest/transform" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/console" "^29.4.3" + "@jest/test-result" "^29.4.3" + "@jest/transform" "^29.4.3" + "@jest/types" "^29.4.3" "@jridgewell/trace-mapping" "^0.3.15" "@types/node" "*" chalk "^4.0.0" @@ -1273,9 +1342,9 @@ istanbul-lib-report "^3.0.0" istanbul-lib-source-maps "^4.0.0" istanbul-reports "^3.1.3" - jest-message-util "^29.4.2" - jest-util "^29.4.2" - jest-worker "^29.4.2" + jest-message-util "^29.4.3" + jest-util "^29.4.3" + jest-worker "^29.4.3" slash "^3.0.0" string-length "^4.0.1" strip-ansi "^6.0.0" @@ -1288,58 +1357,65 @@ dependencies: "@sinclair/typebox" "^0.24.1" -"@jest/schemas@^29.4.0", "@jest/schemas@^29.4.2": +"@jest/schemas@^29.4.0": version "29.4.2" resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.2.tgz#cf7cfe97c5649f518452b176c47ed07486270fc1" integrity sha512-ZrGzGfh31NtdVH8tn0mgJw4khQuNHiKqdzJAFbCaERbyCP9tHlxWuL/mnMu8P7e/+k4puWjI1NOzi/sFsjce/g== dependencies: "@sinclair/typebox" "^0.25.16" -"@jest/source-map@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.2.tgz#f9815d59e25cd3d6828e41489cd239271018d153" - integrity sha512-tIoqV5ZNgYI9XCKXMqbYe5JbumcvyTgNN+V5QW4My033lanijvCD0D4PI9tBw4pRTqWOc00/7X3KVvUh+qnF4Q== +"@jest/schemas@^29.4.2", "@jest/schemas@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/schemas/-/schemas-29.4.3.tgz#39cf1b8469afc40b6f5a2baaa146e332c4151788" + integrity sha512-VLYKXQmtmuEz6IxJsrZwzG9NvtkQsWNnWMsKxqWNu3+CnfzJQhp0WDDKWLVV9hLKr0l3SLLFRqcYHjhtyuDVxg== + dependencies: + "@sinclair/typebox" "^0.25.16" + +"@jest/source-map@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/source-map/-/source-map-29.4.3.tgz#ff8d05cbfff875d4a791ab679b4333df47951d20" + integrity sha512-qyt/mb6rLyd9j1jUts4EQncvS6Yy3PM9HghnNv86QBlV+zdL2inCdK1tuVlL+J+lpiw2BI67qXOrX3UurBqQ1w== dependencies: "@jridgewell/trace-mapping" "^0.3.15" callsites "^3.0.0" graceful-fs "^4.2.9" -"@jest/test-result@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.2.tgz#34b0ba069f2e3072261e4884c8fb6bd15ed6fb8d" - integrity sha512-HZsC3shhiHVvMtP+i55MGR5bPcc3obCFbA5bzIOb8pCjwBZf11cZliJncCgaVUbC5yoQNuGqCkC0Q3t6EItxZA== +"@jest/test-result@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/test-result/-/test-result-29.4.3.tgz#e13d973d16c8c7cc0c597082d5f3b9e7f796ccb8" + integrity sha512-Oi4u9NfBolMq9MASPwuWTlC5WvmNRwI4S8YrQg5R5Gi47DYlBe3sh7ILTqi/LGrK1XUE4XY9KZcQJTH1WJCLLA== dependencies: - "@jest/console" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/console" "^29.4.3" + "@jest/types" "^29.4.3" "@types/istanbul-lib-coverage" "^2.0.0" collect-v8-coverage "^1.0.0" -"@jest/test-sequencer@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.2.tgz#8b48e5bc4af80b42edacaf2a733d4f295edf28fb" - integrity sha512-9Z2cVsD6CcObIVrWigHp2McRJhvCxL27xHtrZFgNC1RwnoSpDx6fZo8QYjJmziFlW9/hr78/3sxF54S8B6v8rg== +"@jest/test-sequencer@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/test-sequencer/-/test-sequencer-29.4.3.tgz#0862e876a22993385a0f3e7ea1cc126f208a2898" + integrity sha512-yi/t2nES4GB4G0mjLc0RInCq/cNr9dNwJxcGg8sslajua5Kb4kmozAc+qPLzplhBgfw1vLItbjyHzUN92UXicw== dependencies: - "@jest/test-result" "^29.4.2" + "@jest/test-result" "^29.4.3" graceful-fs "^4.2.9" - jest-haste-map "^29.4.2" + jest-haste-map "^29.4.3" slash "^3.0.0" -"@jest/transform@^29.4.2": - version "29.4.2" - resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.2.tgz#b24b72dbab4c8675433a80e222d6a8ef4656fb81" - integrity sha512-kf1v5iTJHn7p9RbOsBuc/lcwyPtJaZJt5885C98omWz79NIeD3PfoiiaPSu7JyCyFzNOIzKhmMhQLUhlTL9BvQ== +"@jest/transform@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-29.4.3.tgz#f7d17eac9cb5bb2e1222ea199c7c7e0835e0c037" + integrity sha512-8u0+fBGWolDshsFgPQJESkDa72da/EVwvL+II0trN2DR66wMwiQ9/CihaGfHdlLGFzbBZwMykFtxuwFdZqlKwg== dependencies: "@babel/core" "^7.11.6" - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" "@jridgewell/trace-mapping" "^0.3.15" babel-plugin-istanbul "^6.1.1" chalk "^4.0.0" convert-source-map "^2.0.0" fast-json-stable-stringify "^2.1.0" graceful-fs "^4.2.9" - jest-haste-map "^29.4.2" - jest-regex-util "^29.4.2" - jest-util "^29.4.2" + jest-haste-map "^29.4.3" + jest-regex-util "^29.4.3" + jest-util "^29.4.3" micromatch "^4.0.4" pirates "^4.0.4" slash "^3.0.0" @@ -1357,7 +1433,7 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" -"@jest/types@^29.4.0", "@jest/types@^29.4.2": +"@jest/types@^29.4.0": version "29.4.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.2.tgz#8f724a414b1246b2bfd56ca5225d9e1f39540d82" integrity sha512-CKlngyGP0fwlgC1BRUtPZSiWLBhyS9dKwKmyGxk8Z6M82LBEGB2aLQSg+U1MyLsU+M7UjnlLllBM2BLWKVm/Uw== @@ -1369,6 +1445,18 @@ "@types/yargs" "^17.0.8" chalk "^4.0.0" +"@jest/types@^29.4.3": + version "29.4.3" + resolved "https://registry.yarnpkg.com/@jest/types/-/types-29.4.3.tgz#9069145f4ef09adf10cec1b2901b2d390031431f" + integrity sha512-bPYfw8V65v17m2Od1cv44FH+SiKW7w2Xu7trhcdTLUmSv85rfKsP+qXSjO4KGJr4dtPSzl/gvslZBXctf1qGEA== + dependencies: + "@jest/schemas" "^29.4.3" + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^17.0.8" + chalk "^4.0.0" + "@jridgewell/gen-mapping@^0.1.0": version "0.1.1" resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996" @@ -1409,7 +1497,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== @@ -1600,9 +1688,9 @@ integrity sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA== "@sinclair/typebox@^0.25.16": - version "0.25.21" - resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.21.tgz#763b05a4b472c93a8db29b2c3e359d55b29ce272" - integrity sha512-gFukHN4t8K4+wVC+ECqeqwzBDeFeTzBXroBTqE6vcWrQGbEUpHO7LYdG0f4xnvYq4VOEwITSlHlp0JBAIFMS/g== + version "0.25.23" + resolved "https://registry.yarnpkg.com/@sinclair/typebox/-/typebox-0.25.23.tgz#1c15b0d2b872d89cc0f47c7243eacb447df8b8bd" + integrity sha512-VEB8ygeP42CFLWyAJhN5OklpxUliqdNEUcXb4xZ/CINqtYGTjL5ukluKdKzQ0iWdUxyQ7B0539PAUhHKrCNWSQ== "@sinonjs/commons@^2.0.0": version "2.0.0" @@ -1757,7 +1845,12 @@ resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197" integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA== -"@types/node@*", "@types/node@18": +"@types/node@*": + version "18.14.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.0.tgz#94c47b9217bbac49d4a67a967fdcdeed89ebb7d0" + integrity sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A== + +"@types/node@18": version "18.13.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.13.0.tgz#0400d1e6ce87e9d3032c19eb6c58205b0d3f7850" integrity sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg== @@ -2215,15 +2308,15 @@ available-typed-arrays@^1.0.5: resolved "https://registry.yarnpkg.com/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz#92f95616501069d07d10edb2fc37d3e1c65123b7" integrity sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw== -babel-jest@^29.0.0, babel-jest@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.2.tgz#b17b9f64be288040877cbe2649f91ac3b63b2ba6" - integrity sha512-vcghSqhtowXPG84posYkkkzcZsdayFkubUgbE3/1tuGbX7AQtwCkkNA/wIbB0BMjuCPoqTkiDyKN7Ty7d3uwNQ== +babel-jest@^29.0.0, babel-jest@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-29.4.3.tgz#478b84d430972b277ad67dd631be94abea676792" + integrity sha512-o45Wyn32svZE+LnMVWv/Z4x0SwtLbh4FyGcYtR20kIWd+rdrDZ9Fzq8Ml3MYLD+mZvEdzCjZsCnYZ2jpJyQ+Nw== dependencies: - "@jest/transform" "^29.4.2" + "@jest/transform" "^29.4.3" "@types/babel__core" "^7.1.14" babel-plugin-istanbul "^6.1.1" - babel-preset-jest "^29.4.2" + babel-preset-jest "^29.4.3" chalk "^4.0.0" graceful-fs "^4.2.9" slash "^3.0.0" @@ -2239,10 +2332,10 @@ babel-plugin-istanbul@^6.1.1: istanbul-lib-instrument "^5.0.4" test-exclude "^6.0.0" -babel-plugin-jest-hoist@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.2.tgz#22aa43e255230f02371ffef1cac7eedef58f60bc" - integrity sha512-5HZRCfMeWypFEonRbEkwWXtNS1sQK159LhRVyRuLzyfVBxDy/34Tr/rg4YVi0SScSJ4fqeaR/OIeceJ/LaQ0pQ== +babel-plugin-jest-hoist@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.4.3.tgz#ad1dfb5d31940957e00410ef7d9b2aa94b216101" + integrity sha512-mB6q2q3oahKphy5V7CpnNqZOCkxxZ9aokf1eh82Dy3jQmg4xvM1tGrh5y6BQUJh4a3Pj9+eLfwvAZ7VNKg7H8Q== dependencies: "@babel/template" "^7.3.3" "@babel/types" "^7.3.3" @@ -2291,12 +2384,12 @@ babel-preset-current-node-syntax@^1.0.0: "@babel/plugin-syntax-optional-chaining" "^7.8.3" "@babel/plugin-syntax-top-level-await" "^7.8.3" -babel-preset-jest@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.2.tgz#f0b20c6a79a9f155515e72a2d4f537fe002a4e38" - integrity sha512-ecWdaLY/8JyfUDr0oELBMpj3R5I1L6ZqG+kRJmwqfHtLWuPrJStR0LUkvUhfykJWTsXXMnohsayN/twltBbDrQ== +babel-preset-jest@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-29.4.3.tgz#bb926b66ae253b69c6e3ef87511b8bb5c53c5b52" + integrity sha512-gWx6COtSuma6n9bw+8/F+2PCXrIgxV/D1TJFnp6OyBK2cxPWg0K9p/sriNYeifKjpUkMViWQ09DSWtzJQRETsw== dependencies: - babel-plugin-jest-hoist "^29.4.2" + babel-plugin-jest-hoist "^29.4.3" babel-preset-current-node-syntax "^1.0.0" babel-runtime@^6.26.0: @@ -2667,11 +2760,16 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001449: +caniuse-lite@^1.0.30001400: version "1.0.30001451" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz#2e197c698fc1373d63e1406d6607ea4617c613f1" integrity sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w== +caniuse-lite@^1.0.30001449: + version "1.0.30001457" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301" + integrity sha512-SDIV6bgE1aVbK6XyxdURbUE89zY7+k1BBBaOwYwkNCglXlel/E7mELiHC64HQ+W0xSKlqWhV9Wh7iHxUjMs4fA== + center-align@^0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" @@ -2724,7 +2822,12 @@ chokidar@^3.4.0: optionalDependencies: fsevents "~2.3.2" -ci-info@^3.2.0, ci-info@^3.6.1: +ci-info@^3.2.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.8.0.tgz#81408265a5380c929f0bc665d62256628ce9ef91" + integrity sha512-eXTggHWSooYhq49F2opQhuHWgzucfF2YgODK4e1566GQs5BIfP30B0oenwBJHfWxAs2fyPB1s7Mg949zLf61Yw== + +ci-info@^3.6.1: version "3.7.1" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-3.7.1.tgz#708a6cdae38915d597afdf3b145f2f8e1ff55f3f" integrity sha512-4jYS4MOAaCIStSRwiuxc4B8MYhIe676yO1sYGzARnjXkWpmzZMMYxY6zu8WYWDhSuth5zhrQ1rhNSibyyvv4/w== @@ -3161,10 +3264,10 @@ diff-sequences@^28.1.1: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-28.1.1.tgz#9989dc731266dc2903457a70e996f3a041913ac6" integrity sha512-FU0iFaH/E23a+a718l8Qa/19bF9p06kgE0KipMOMadwa3SjnaElKzPaUC0vnibs6/B/9ni97s61mcejk8W1fQw== -diff-sequences@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.2.tgz#711fe6bd8a5869fe2539cee4a5152425ff671fda" - integrity sha512-R6P0Y6PrsH3n4hUXxL3nns0rbRk6Q33js3ygJBeEpbzLzgcNuJ61+u0RXasFpTKISw99TxUzFnumSnRLsjhLaw== +diff-sequences@^29.4.2, diff-sequences@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-29.4.3.tgz#9314bc1fabe09267ffeca9cbafc457d8499a13f2" + integrity sha512-ofrBgwpPhCD85kMKtE9RYFFq6OC1A89oW2vvgWZNCwxrUpRUILopY7lsYyMDSjc8g6U6aiO0Qubg6r4Wgt5ZnA== diffie-hellman@^5.0.0: version "5.0.3" @@ -3234,11 +3337,16 @@ duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: dependencies: readable-stream "^2.0.2" -electron-to-chromium@^1.4.251, electron-to-chromium@^1.4.284: +electron-to-chromium@^1.4.251: version "1.4.292" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.292.tgz#e3a3dca3780c8ce01e2c1866b5ec2fbe31c423e3" integrity sha512-ESWOSyJy5odDlE8wvh5NNAMORv4r6assPwIPGHEMWrWD0SONXcG/xT+9aD9CQyeRwyYDPo6dJT4Bbeg5uevVQQ== +electron-to-chromium@^1.4.284: + version "1.4.305" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.305.tgz#e4dfe3e06ab783f33171f9bde9e8ed092510fcd0" + integrity sha512-WETy6tG0CT5gm1O+xCbyapWNsCcmIvrn4NHViIGYo2AT8FV2qUCXdaB+WqYxSv/vS5mFqhBYnfZAAkVArjBmUg== + elliptic@^6.5.3: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -3737,16 +3845,16 @@ expect@^29.0.0: jest-message-util "^29.4.0" jest-util "^29.4.0" -expect@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.2.tgz#2ae34eb88de797c64a1541ad0f1e2ea8a7a7b492" - integrity sha512-+JHYg9O3hd3RlICG90OPVjRkPBoiUH7PxvDVMnRiaq1g6JUgZStX514erMl0v2Dc5SkfVbm7ztqbd6qHHPn+mQ== +expect@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-29.4.3.tgz#5e47757316df744fe3b8926c3ae8a3ebdafff7fe" + integrity sha512-uC05+Q7eXECFpgDrHdXA4k2rpMyStAYPItEDLyQDo5Ta7fVkJnNA/4zh/OIVkVVNZ1oOK1PipQoyNjuZ6sz6Dg== dependencies: - "@jest/expect-utils" "^29.4.2" - jest-get-type "^29.4.2" - jest-matcher-utils "^29.4.2" - jest-message-util "^29.4.2" - jest-util "^29.4.2" + "@jest/expect-utils" "^29.4.3" + jest-get-type "^29.4.3" + jest-matcher-utils "^29.4.3" + jest-message-util "^29.4.3" + jest-util "^29.4.3" ext@^1.1.2: version "1.7.0" @@ -4606,82 +4714,82 @@ istanbul-reports@^3.1.3, istanbul-reports@^3.1.4: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" -jest-changed-files@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.2.tgz#bee1fafc8b620d6251423d1978a0080546bc4376" - integrity sha512-Qdd+AXdqD16PQa+VsWJpxR3kN0JyOCX1iugQfx5nUgAsI4gwsKviXkpclxOK9ZnwaY2IQVHz+771eAvqeOlfuw== +jest-changed-files@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-29.4.3.tgz#7961fe32536b9b6d5c28dfa0abcfab31abcf50a7" + integrity sha512-Vn5cLuWuwmi2GNNbokPOEcvrXGSGrqVnPEZV7rC6P7ck07Dyw9RFnvWglnupSh+hGys0ajGtw/bc2ZgweljQoQ== dependencies: execa "^5.0.0" p-limit "^3.1.0" -jest-circus@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.2.tgz#2d00c04baefd0ee2a277014cd494d4b5970663ed" - integrity sha512-wW3ztp6a2P5c1yOc1Cfrt5ozJ7neWmqeXm/4SYiqcSriyisgq63bwFj1NuRdSR5iqS0CMEYwSZd89ZA47W9zUg== +jest-circus@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-circus/-/jest-circus-29.4.3.tgz#fff7be1cf5f06224dd36a857d52a9efeb005ba04" + integrity sha512-Vw/bVvcexmdJ7MLmgdT3ZjkJ3LKu8IlpefYokxiqoZy6OCQ2VAm6Vk3t/qHiAGUXbdbJKJWnc8gH3ypTbB/OBw== dependencies: - "@jest/environment" "^29.4.2" - "@jest/expect" "^29.4.2" - "@jest/test-result" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/environment" "^29.4.3" + "@jest/expect" "^29.4.3" + "@jest/test-result" "^29.4.3" + "@jest/types" "^29.4.3" "@types/node" "*" chalk "^4.0.0" co "^4.6.0" dedent "^0.7.0" is-generator-fn "^2.0.0" - jest-each "^29.4.2" - jest-matcher-utils "^29.4.2" - jest-message-util "^29.4.2" - jest-runtime "^29.4.2" - jest-snapshot "^29.4.2" - jest-util "^29.4.2" + jest-each "^29.4.3" + jest-matcher-utils "^29.4.3" + jest-message-util "^29.4.3" + jest-runtime "^29.4.3" + jest-snapshot "^29.4.3" + jest-util "^29.4.3" p-limit "^3.1.0" - pretty-format "^29.4.2" + pretty-format "^29.4.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-cli@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.2.tgz#94a2f913a0a7a49d11bee98ad88bf48baae941f4" - integrity sha512-b+eGUtXq/K2v7SH3QcJvFvaUaCDS1/YAZBYz0m28Q/Ppyr+1qNaHmVYikOrbHVbZqYQs2IeI3p76uy6BWbXq8Q== +jest-cli@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-29.4.3.tgz#fe31fdd0c90c765f392b8b7c97e4845071cd2163" + integrity sha512-PiiAPuFNfWWolCE6t3ZrDXQc6OsAuM3/tVW0u27UWc1KE+n/HSn5dSE6B2juqN7WP+PP0jAcnKtGmI4u8GMYCg== dependencies: - "@jest/core" "^29.4.2" - "@jest/test-result" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/core" "^29.4.3" + "@jest/test-result" "^29.4.3" + "@jest/types" "^29.4.3" chalk "^4.0.0" exit "^0.1.2" graceful-fs "^4.2.9" import-local "^3.0.2" - jest-config "^29.4.2" - jest-util "^29.4.2" - jest-validate "^29.4.2" + jest-config "^29.4.3" + jest-util "^29.4.3" + jest-validate "^29.4.3" prompts "^2.0.1" yargs "^17.3.1" -jest-config@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.2.tgz#15386dd9ed2f7059516915515f786b8836a98f07" - integrity sha512-919CtnXic52YM0zW4C1QxjG6aNueX1kBGthuMtvFtRTAxhKfJmiXC9qwHmi6o2josjbDz8QlWyY55F1SIVmCWA== +jest-config@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-29.4.3.tgz#fca9cdfe6298ae6d04beef1624064d455347c978" + integrity sha512-eCIpqhGnIjdUCXGtLhz4gdDoxKSWXKjzNcc5r+0S1GKOp2fwOipx5mRcwa9GB/ArsxJ1jlj2lmlD9bZAsBxaWQ== dependencies: "@babel/core" "^7.11.6" - "@jest/test-sequencer" "^29.4.2" - "@jest/types" "^29.4.2" - babel-jest "^29.4.2" + "@jest/test-sequencer" "^29.4.3" + "@jest/types" "^29.4.3" + babel-jest "^29.4.3" chalk "^4.0.0" ci-info "^3.2.0" deepmerge "^4.2.2" glob "^7.1.3" graceful-fs "^4.2.9" - jest-circus "^29.4.2" - jest-environment-node "^29.4.2" - jest-get-type "^29.4.2" - jest-regex-util "^29.4.2" - jest-resolve "^29.4.2" - jest-runner "^29.4.2" - jest-util "^29.4.2" - jest-validate "^29.4.2" + jest-circus "^29.4.3" + jest-environment-node "^29.4.3" + jest-get-type "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.4.3" + jest-runner "^29.4.3" + jest-util "^29.4.3" + jest-validate "^29.4.3" micromatch "^4.0.4" parse-json "^5.2.0" - pretty-format "^29.4.2" + pretty-format "^29.4.3" slash "^3.0.0" strip-json-comments "^3.1.1" @@ -4695,7 +4803,7 @@ jest-diff@^28.1.3: jest-get-type "^28.0.2" pretty-format "^28.1.3" -jest-diff@^29.4.0, jest-diff@^29.4.2: +jest-diff@^29.4.0: version "29.4.2" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.2.tgz#b88502d5dc02d97f6512d73c37da8b36f49b4871" integrity sha512-EK8DSajVtnjx9sa1BkjZq3mqChm2Cd8rIzdXkQMA8e0wuXq53ypz6s5o5V8HRZkoEt2ywJ3eeNWFKWeYr8HK4g== @@ -4705,86 +4813,101 @@ jest-diff@^29.4.0, jest-diff@^29.4.2: jest-get-type "^29.4.2" pretty-format "^29.4.2" -jest-docblock@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.2.tgz#c78a95eedf9a24c0a6cc16cf2abdc4b8b0f2531b" - integrity sha512-dV2JdahgClL34Y5vLrAHde3nF3yo2jKRH+GIYJuCpfqwEJZcikzeafVTGAjbOfKPG17ez9iWXwUYp7yefeCRag== +jest-diff@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-29.4.3.tgz#42f4eb34d0bf8c0fb08b0501069b87e8e84df347" + integrity sha512-YB+ocenx7FZ3T5O9lMVMeLYV4265socJKtkwgk/6YUz/VsEzYDkiMuMhWzZmxm3wDRQvayJu/PjkjjSkjoHsCA== + dependencies: + chalk "^4.0.0" + diff-sequences "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.4.3" + +jest-docblock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-29.4.3.tgz#90505aa89514a1c7dceeac1123df79e414636ea8" + integrity sha512-fzdTftThczeSD9nZ3fzA/4KkHtnmllawWrXO69vtI+L9WjEIuXWs4AmyME7lN5hU7dB0sHhuPfcKofRsUb/2Fg== dependencies: detect-newline "^3.0.0" -jest-each@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.2.tgz#e1347aff1303f4c35470827a62c029d389c5d44a" - integrity sha512-trvKZb0JYiCndc55V1Yh0Luqi7AsAdDWpV+mKT/5vkpnnFQfuQACV72IoRV161aAr6kAVIBpmYzwhBzm34vQkA== +jest-each@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-29.4.3.tgz#a434c199a2f6151c5e3dc80b2d54586bdaa72819" + integrity sha512-1ElHNAnKcbJb/b+L+7j0/w7bDvljw4gTv1wL9fYOczeJrbTbkMGQ5iQPFJ3eFQH19VPTx1IyfePdqSpePKss7Q== dependencies: - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" chalk "^4.0.0" - jest-get-type "^29.4.2" - jest-util "^29.4.2" - pretty-format "^29.4.2" + jest-get-type "^29.4.3" + jest-util "^29.4.3" + pretty-format "^29.4.3" jest-environment-jsdom@^29.0.0: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.4.2.tgz#0cf95ad846949280dd58bc91a9ca463b6b232dd8" - integrity sha512-v1sH4Q0JGM+LPEGqHNM+m+uTMf3vpXpKiuDYqWUAh+0c9+nc7scGE+qTR5JuE+OOTDnwfzPgcv9sMq6zWAOaVg== + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-29.4.3.tgz#bd8ed3808e6d3f616403fbaf8354f77019613d90" + integrity sha512-rFjf8JXrw3OjUzzmSE5l0XjMj0/MSVEUMCSXBGPDkfwb1T03HZI7iJSL0cGctZApPSyJxbjyKDVxkZuyhHkuTw== dependencies: - "@jest/environment" "^29.4.2" - "@jest/fake-timers" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/environment" "^29.4.3" + "@jest/fake-timers" "^29.4.3" + "@jest/types" "^29.4.3" "@types/jsdom" "^20.0.0" "@types/node" "*" - jest-mock "^29.4.2" - jest-util "^29.4.2" + jest-mock "^29.4.3" + jest-util "^29.4.3" jsdom "^20.0.0" -jest-environment-node@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.2.tgz#0eab835b41e25fd0c1a72f62665fc8db08762ad2" - integrity sha512-MLPrqUcOnNBc8zTOfqBbxtoa8/Ee8tZ7UFW7hRDQSUT+NGsvS96wlbHGTf+EFAT9KC3VNb7fWEM6oyvmxtE/9w== +jest-environment-node@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-29.4.3.tgz#579c4132af478befc1889ddc43c2413a9cdbe014" + integrity sha512-gAiEnSKF104fsGDXNkwk49jD/0N0Bqu2K9+aMQXA6avzsA9H3Fiv1PW2D+gzbOSR705bWd2wJZRFEFpV0tXISg== dependencies: - "@jest/environment" "^29.4.2" - "@jest/fake-timers" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/environment" "^29.4.3" + "@jest/fake-timers" "^29.4.3" + "@jest/types" "^29.4.3" "@types/node" "*" - jest-mock "^29.4.2" - jest-util "^29.4.2" + jest-mock "^29.4.3" + jest-util "^29.4.3" jest-get-type@^28.0.2: version "28.0.2" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-28.0.2.tgz#34622e628e4fdcd793d46db8a242227901fcf203" integrity sha512-ioj2w9/DxSYHfOm5lJKCdcAmPJzQXmbM/Url3rhlghrPvT3tt+7a/+oXc9azkKmLvoiXjtV83bEWqi+vs5nlPA== -jest-get-type@^29.2.0, jest-get-type@^29.4.2: +jest-get-type@^29.2.0: version "29.4.2" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.2.tgz#7cb63f154bca8d8f57364d01614477d466fa43fe" integrity sha512-vERN30V5i2N6lqlFu4ljdTqQAgrkTFMC9xaIIfOPYBw04pufjXRty5RuXBiB1d72tGbURa/UgoiHB90ruOSivg== -jest-haste-map@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.2.tgz#9112df3f5121e643f1b2dcbaa86ab11b0b90b49a" - integrity sha512-WkUgo26LN5UHPknkezrBzr7lUtV1OpGsp+NfXbBwHztsFruS3gz+AMTTBcEklvi8uPzpISzYjdKXYZQJXBnfvw== +jest-get-type@^29.4.2, jest-get-type@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-29.4.3.tgz#1ab7a5207c995161100b5187159ca82dd48b3dd5" + integrity sha512-J5Xez4nRRMjk8emnTpWrlkyb9pfRQQanDrvWHhsR1+VUfbwxi30eVcZFlcdGInRibU4G5LwHXpI7IRHU0CY+gg== + +jest-haste-map@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-29.4.3.tgz#085a44283269e7ace0645c63a57af0d2af6942e2" + integrity sha512-eZIgAS8tvm5IZMtKlR8Y+feEOMfo2pSQkmNbufdbMzMSn9nitgGxF1waM/+LbryO3OkMcKS98SUb+j/cQxp/vQ== dependencies: - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" "@types/graceful-fs" "^4.1.3" "@types/node" "*" anymatch "^3.0.3" fb-watchman "^2.0.0" graceful-fs "^4.2.9" - jest-regex-util "^29.4.2" - jest-util "^29.4.2" - jest-worker "^29.4.2" + jest-regex-util "^29.4.3" + jest-util "^29.4.3" + jest-worker "^29.4.3" micromatch "^4.0.4" walker "^1.0.8" optionalDependencies: fsevents "^2.3.2" -jest-leak-detector@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.2.tgz#8f05c6680e0cb46a1d577c0d3da9793bed3ea97b" - integrity sha512-Wa62HuRJmWXtX9F00nUpWlrbaH5axeYCdyRsOs/+Rb1Vb6+qWTlB5rKwCCRKtorM7owNwKsyJ8NRDUcZ8ghYUA== +jest-leak-detector@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-29.4.3.tgz#2b35191d6b35aa0256e63a9b79b0f949249cf23a" + integrity sha512-9yw4VC1v2NspMMeV3daQ1yXPNxMgCzwq9BocCwYrRgXe4uaEJPAN0ZK37nFBhcy3cUwEVstFecFLaTHpF7NiGA== dependencies: - jest-get-type "^29.4.2" - pretty-format "^29.4.2" + jest-get-type "^29.4.3" + pretty-format "^29.4.3" jest-localstorage-mock@^2.4.6: version "2.4.26" @@ -4811,15 +4934,15 @@ jest-matcher-utils@^29.4.0: jest-get-type "^29.2.0" pretty-format "^29.4.0" -jest-matcher-utils@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.2.tgz#08d0bf5abf242e3834bec92c7ef5071732839e85" - integrity sha512-EZaAQy2je6Uqkrm6frnxBIdaWtSYFoR8SVb2sNLAtldswlR/29JAgx+hy67llT3+hXBaLB0zAm5UfeqerioZyg== +jest-matcher-utils@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-29.4.3.tgz#ea68ebc0568aebea4c4213b99f169ff786df96a0" + integrity sha512-TTciiXEONycZ03h6R6pYiZlSkvYgT0l8aa49z/DLSGYjex4orMUcafuLXYyyEDWB1RKglq00jzwY00Ei7yFNVg== dependencies: chalk "^4.0.0" - jest-diff "^29.4.2" - jest-get-type "^29.4.2" - pretty-format "^29.4.2" + jest-diff "^29.4.3" + jest-get-type "^29.4.3" + pretty-format "^29.4.3" jest-message-util@^28.1.3: version "28.1.3" @@ -4851,123 +4974,122 @@ jest-message-util@^29.4.0: slash "^3.0.0" stack-utils "^2.0.3" -jest-message-util@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.2.tgz#309a2924eae6ca67cf7f25781a2af1902deee717" - integrity sha512-SElcuN4s6PNKpOEtTInjOAA8QvItu0iugkXqhYyguRvQoXapg5gN+9RQxLAkakChZA7Y26j6yUCsFWN+hlKD6g== +jest-message-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-29.4.3.tgz#65b5280c0fdc9419503b49d4f48d4999d481cb5b" + integrity sha512-1Y8Zd4ZCN7o/QnWdMmT76If8LuDv23Z1DRovBj/vcSFNlGCJGoO8D1nJDw1AdyAGUk0myDLFGN5RbNeJyCRGCw== dependencies: "@babel/code-frame" "^7.12.13" - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" "@types/stack-utils" "^2.0.0" chalk "^4.0.0" graceful-fs "^4.2.9" micromatch "^4.0.4" - pretty-format "^29.4.2" + pretty-format "^29.4.3" slash "^3.0.0" stack-utils "^2.0.3" -jest-mock@^29.0.0, jest-mock@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.2.tgz#e1054be66fb3e975d26d4528fcde6979e4759de8" - integrity sha512-x1FSd4Gvx2yIahdaIKoBjwji6XpboDunSJ95RpntGrYulI1ByuYQCKN/P7hvk09JB74IonU3IPLdkutEWYt++g== +jest-mock@^29.0.0, jest-mock@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-29.4.3.tgz#23d84a20a74cdfff0510fdbeefb841ed57b0fe7e" + integrity sha512-LjFgMg+xed9BdkPMyIJh+r3KeHt1klXPJYBULXVVAkbTaaKjPX1o1uVCAZADMEp/kOxGTwy/Ot8XbvgItOrHEg== dependencies: - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" "@types/node" "*" - jest-util "^29.4.2" + jest-util "^29.4.3" jest-pnp-resolver@^1.2.2: version "1.2.3" resolved "https://registry.yarnpkg.com/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz#930b1546164d4ad5937d5540e711d4d38d4cad2e" integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w== -jest-regex-util@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.2.tgz#19187cca35d301f8126cf7a021dd4dcb7b58a1ca" - integrity sha512-XYZXOqUl1y31H6VLMrrUL1ZhXuiymLKPz0BO1kEeR5xER9Tv86RZrjTm74g5l9bPJQXA/hyLdaVPN/sdqfteig== +jest-regex-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-29.4.3.tgz#a42616141e0cae052cfa32c169945d00c0aa0bb8" + integrity sha512-O4FglZaMmWXbGHSQInfXewIsd1LMn9p3ZXB/6r4FOkyhX2/iP/soMG98jGvk/A3HAN78+5VWcBGO0BJAPRh4kg== -jest-resolve-dependencies@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.2.tgz#6359db606f5967b68ca8bbe9dbc07a4306c12bf7" - integrity sha512-6pL4ptFw62rjdrPk7rRpzJYgcRqRZNsZTF1VxVTZMishbO6ObyWvX57yHOaNGgKoADtAHRFYdHQUEvYMJATbDg== +jest-resolve-dependencies@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-29.4.3.tgz#9ad7f23839a6d88cef91416bda9393a6e9fd1da5" + integrity sha512-uvKMZAQ3nmXLH7O8WAOhS5l0iWyT3WmnJBdmIHiV5tBbdaDZ1wqtNX04FONGoaFvSOSHBJxnwAVnSn1WHdGVaw== dependencies: - jest-regex-util "^29.4.2" - jest-snapshot "^29.4.2" + jest-regex-util "^29.4.3" + jest-snapshot "^29.4.3" -jest-resolve@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.2.tgz#8831f449671d08d161fe493003f61dc9b55b808e" - integrity sha512-RtKWW0mbR3I4UdkOrW7552IFGLYQ5AF9YrzD0FnIOkDu0rAMlA5/Y1+r7lhCAP4nXSBTaE7ueeqj6IOwZpgoqw== +jest-resolve@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-29.4.3.tgz#3c5b5c984fa8a763edf9b3639700e1c7900538e2" + integrity sha512-GPokE1tzguRyT7dkxBim4wSx6E45S3bOQ7ZdKEG+Qj0Oac9+6AwJPCk0TZh5Vu0xzeX4afpb+eDmgbmZFFwpOw== dependencies: chalk "^4.0.0" graceful-fs "^4.2.9" - jest-haste-map "^29.4.2" + jest-haste-map "^29.4.3" jest-pnp-resolver "^1.2.2" - jest-util "^29.4.2" - jest-validate "^29.4.2" + jest-util "^29.4.3" + jest-validate "^29.4.3" resolve "^1.20.0" resolve.exports "^2.0.0" slash "^3.0.0" -jest-runner@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.2.tgz#2bcecf72303369df4ef1e6e983c22a89870d5125" - integrity sha512-wqwt0drm7JGjwdH+x1XgAl+TFPH7poowMguPQINYxaukCqlczAcNLJiK+OLxUxQAEWMdy+e6nHZlFHO5s7EuRg== - dependencies: - "@jest/console" "^29.4.2" - "@jest/environment" "^29.4.2" - "@jest/test-result" "^29.4.2" - "@jest/transform" "^29.4.2" - "@jest/types" "^29.4.2" +jest-runner@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-29.4.3.tgz#68dc82c68645eda12bea42b5beece6527d7c1e5e" + integrity sha512-GWPTEiGmtHZv1KKeWlTX9SIFuK19uLXlRQU43ceOQ2hIfA5yPEJC7AMkvFKpdCHx6pNEdOD+2+8zbniEi3v3gA== + dependencies: + "@jest/console" "^29.4.3" + "@jest/environment" "^29.4.3" + "@jest/test-result" "^29.4.3" + "@jest/transform" "^29.4.3" + "@jest/types" "^29.4.3" "@types/node" "*" chalk "^4.0.0" emittery "^0.13.1" graceful-fs "^4.2.9" - jest-docblock "^29.4.2" - jest-environment-node "^29.4.2" - jest-haste-map "^29.4.2" - jest-leak-detector "^29.4.2" - jest-message-util "^29.4.2" - jest-resolve "^29.4.2" - jest-runtime "^29.4.2" - jest-util "^29.4.2" - jest-watcher "^29.4.2" - jest-worker "^29.4.2" + jest-docblock "^29.4.3" + jest-environment-node "^29.4.3" + jest-haste-map "^29.4.3" + jest-leak-detector "^29.4.3" + jest-message-util "^29.4.3" + jest-resolve "^29.4.3" + jest-runtime "^29.4.3" + jest-util "^29.4.3" + jest-watcher "^29.4.3" + jest-worker "^29.4.3" p-limit "^3.1.0" source-map-support "0.5.13" -jest-runtime@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.2.tgz#d86b764c5b95d76cb26ed1f32644e99de5d5c134" - integrity sha512-3fque9vtpLzGuxT9eZqhxi+9EylKK/ESfhClv4P7Y9sqJPs58LjVhTt8jaMp/pRO38agll1CkSu9z9ieTQeRrw== - dependencies: - "@jest/environment" "^29.4.2" - "@jest/fake-timers" "^29.4.2" - "@jest/globals" "^29.4.2" - "@jest/source-map" "^29.4.2" - "@jest/test-result" "^29.4.2" - "@jest/transform" "^29.4.2" - "@jest/types" "^29.4.2" +jest-runtime@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-29.4.3.tgz#f25db9874dcf35a3ab27fdaabca426666cc745bf" + integrity sha512-F5bHvxSH+LvLV24vVB3L8K467dt3y3dio6V3W89dUz9nzvTpqd/HcT9zfYKL2aZPvD63vQFgLvaUX/UpUhrP6Q== + dependencies: + "@jest/environment" "^29.4.3" + "@jest/fake-timers" "^29.4.3" + "@jest/globals" "^29.4.3" + "@jest/source-map" "^29.4.3" + "@jest/test-result" "^29.4.3" + "@jest/transform" "^29.4.3" + "@jest/types" "^29.4.3" "@types/node" "*" chalk "^4.0.0" cjs-module-lexer "^1.0.0" collect-v8-coverage "^1.0.0" glob "^7.1.3" graceful-fs "^4.2.9" - jest-haste-map "^29.4.2" - jest-message-util "^29.4.2" - jest-mock "^29.4.2" - jest-regex-util "^29.4.2" - jest-resolve "^29.4.2" - jest-snapshot "^29.4.2" - jest-util "^29.4.2" - semver "^7.3.5" + jest-haste-map "^29.4.3" + jest-message-util "^29.4.3" + jest-mock "^29.4.3" + jest-regex-util "^29.4.3" + jest-resolve "^29.4.3" + jest-snapshot "^29.4.3" + jest-util "^29.4.3" slash "^3.0.0" strip-bom "^4.0.0" -jest-snapshot@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.2.tgz#ba1fb9abb279fd2c85109ff1757bc56b503bbb3a" - integrity sha512-PdfubrSNN5KwroyMH158R23tWcAXJyx4pvSvWls1dHoLCaUhGul9rsL3uVjtqzRpkxlkMavQjGuWG1newPgmkw== +jest-snapshot@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-29.4.3.tgz#183d309371450d9c4a3de7567ed2151eb0e91145" + integrity sha512-NGlsqL0jLPDW91dz304QTM/SNO99lpcSYYAjNiX0Ou+sSGgkanKBcSjCfp/pqmiiO1nQaOyLp6XQddAzRcx3Xw== dependencies: "@babel/core" "^7.11.6" "@babel/generator" "^7.7.2" @@ -4975,23 +5097,23 @@ jest-snapshot@^29.4.2: "@babel/plugin-syntax-typescript" "^7.7.2" "@babel/traverse" "^7.7.2" "@babel/types" "^7.3.3" - "@jest/expect-utils" "^29.4.2" - "@jest/transform" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/expect-utils" "^29.4.3" + "@jest/transform" "^29.4.3" + "@jest/types" "^29.4.3" "@types/babel__traverse" "^7.0.6" "@types/prettier" "^2.1.5" babel-preset-current-node-syntax "^1.0.0" chalk "^4.0.0" - expect "^29.4.2" + expect "^29.4.3" graceful-fs "^4.2.9" - jest-diff "^29.4.2" - jest-get-type "^29.4.2" - jest-haste-map "^29.4.2" - jest-matcher-utils "^29.4.2" - jest-message-util "^29.4.2" - jest-util "^29.4.2" + jest-diff "^29.4.3" + jest-get-type "^29.4.3" + jest-haste-map "^29.4.3" + jest-matcher-utils "^29.4.3" + jest-message-util "^29.4.3" + jest-util "^29.4.3" natural-compare "^1.4.0" - pretty-format "^29.4.2" + pretty-format "^29.4.3" semver "^7.3.5" jest-util@^28.1.3: @@ -5018,63 +5140,63 @@ jest-util@^29.4.0: graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-util@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.2.tgz#3db8580b295df453a97de4a1b42dd2578dabd2c2" - integrity sha512-wKnm6XpJgzMUSRFB7YF48CuwdzuDIHenVuoIb1PLuJ6F+uErZsuDkU+EiExkChf6473XcawBrSfDSnXl+/YG4g== +jest-util@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-29.4.3.tgz#851a148e23fc2b633c55f6dad2e45d7f4579f496" + integrity sha512-ToSGORAz4SSSoqxDSylWX8JzkOQR7zoBtNRsA7e+1WUX5F8jrOwaNpuh1YfJHJKDHXLHmObv5eOjejUd+/Ws+Q== dependencies: - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" "@types/node" "*" chalk "^4.0.0" ci-info "^3.2.0" graceful-fs "^4.2.9" picomatch "^2.2.3" -jest-validate@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.2.tgz#3b3f8c4910ab9a3442d2512e2175df6b3f77b915" - integrity sha512-tto7YKGPJyFbhcKhIDFq8B5od+eVWD/ySZ9Tvcp/NGCvYA4RQbuzhbwYWtIjMT5W5zA2W0eBJwu4HVw34d5G6Q== +jest-validate@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-29.4.3.tgz#a13849dec4f9e95446a7080ad5758f58fa88642f" + integrity sha512-J3u5v7aPQoXPzaar6GndAVhdQcZr/3osWSgTeKg5v574I9ybX/dTyH0AJFb5XgXIB7faVhf+rS7t4p3lL9qFaw== dependencies: - "@jest/types" "^29.4.2" + "@jest/types" "^29.4.3" camelcase "^6.2.0" chalk "^4.0.0" - jest-get-type "^29.4.2" + jest-get-type "^29.4.3" leven "^3.1.0" - pretty-format "^29.4.2" + pretty-format "^29.4.3" -jest-watcher@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.2.tgz#09c0f4c9a9c7c0807fcefb1445b821c6f7953b7c" - integrity sha512-onddLujSoGiMJt+tKutehIidABa175i/Ays+QvKxCqBwp7fvxP3ZhKsrIdOodt71dKxqk4sc0LN41mWLGIK44w== +jest-watcher@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-29.4.3.tgz#e503baa774f0c2f8f3c8db98a22ebf885f19c384" + integrity sha512-zwlXH3DN3iksoIZNk73etl1HzKyi5FuQdYLnkQKm5BW4n8HpoG59xSwpVdFrnh60iRRaRBGw0gcymIxjJENPcA== dependencies: - "@jest/test-result" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/test-result" "^29.4.3" + "@jest/types" "^29.4.3" "@types/node" "*" ansi-escapes "^4.2.1" chalk "^4.0.0" emittery "^0.13.1" - jest-util "^29.4.2" + jest-util "^29.4.3" string-length "^4.0.1" -jest-worker@^29.4.2: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.2.tgz#d9b2c3bafc69311d84d94e7fb45677fc8976296f" - integrity sha512-VIuZA2hZmFyRbchsUCHEehoSf2HEl0YVF8SDJqtPnKorAaBuh42V8QsLnde0XP5F6TyCynGPEGgBOn3Fc+wZGw== +jest-worker@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-29.4.3.tgz#9a4023e1ea1d306034237c7133d7da4240e8934e" + integrity sha512-GLHN/GTAAMEy5BFdvpUfzr9Dr80zQqBrh0fz1mtRMe05hqP45+HfQltu7oTBfduD0UeZs09d+maFtFYAXFWvAA== dependencies: "@types/node" "*" - jest-util "^29.4.2" + jest-util "^29.4.3" merge-stream "^2.0.0" supports-color "^8.0.0" jest@^29.0.0: - version "29.4.2" - resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.2.tgz#4c2127d03a71dc187f386156ef155dbf323fb7be" - integrity sha512-+5hLd260vNIHu+7ZgMIooSpKl7Jp5pHKb51e73AJU3owd5dEo/RfVwHbA/na3C/eozrt3hJOLGf96c7EWwIAzg== + version "29.4.3" + resolved "https://registry.yarnpkg.com/jest/-/jest-29.4.3.tgz#1b8be541666c6feb99990fd98adac4737e6e6386" + integrity sha512-XvK65feuEFGZT8OO0fB/QAQS+LGHvQpaadkH5p47/j3Ocqq3xf2pK9R+G0GzgfuhXVxEv76qCOOcMb5efLk6PA== dependencies: - "@jest/core" "^29.4.2" - "@jest/types" "^29.4.2" + "@jest/core" "^29.4.3" + "@jest/types" "^29.4.3" import-local "^3.0.2" - jest-cli "^29.4.2" + jest-cli "^29.4.3" jju@~1.4.0: version "1.4.0" @@ -5956,7 +6078,7 @@ pretty-format@^29.0.0: ansi-styles "^5.0.0" react-is "^18.0.0" -pretty-format@^29.4.0, pretty-format@^29.4.2: +pretty-format@^29.4.0: version "29.4.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.2.tgz#64bf5ccc0d718c03027d94ac957bdd32b3fb2401" integrity sha512-qKlHR8yFVCbcEWba0H0TOC8dnLlO4vPlyEjRPw31FZ2Rupy9nLa8ZLbYny8gWEl8CkEhJqAE6IzdNELTBVcBEg== @@ -5965,6 +6087,15 @@ pretty-format@^29.4.0, pretty-format@^29.4.2: ansi-styles "^5.0.0" react-is "^18.0.0" +pretty-format@^29.4.2, pretty-format@^29.4.3: + version "29.4.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-29.4.3.tgz#25500ada21a53c9e8423205cf0337056b201244c" + integrity sha512-cvpcHTc42lcsvOOAzd3XuNWTcvk1Jmnzqeu+WsOuiPmxUJTnkbAcFNsRKvEpBEUFVUgy/GTZLulZDcDEi+CIlA== + dependencies: + "@jest/schemas" "^29.4.3" + ansi-styles "^5.0.0" + react-is "^18.0.0" + private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -7317,7 +7448,7 @@ uuid@9: resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== -v8-to-istanbul@^9.0.0, v8-to-istanbul@^9.0.1: +v8-to-istanbul@^9.0.0: version "9.0.1" resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz#b6f994b0b5d4ef255e17a0d17dc444a9f5132fa4" integrity sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w== @@ -7326,6 +7457,15 @@ v8-to-istanbul@^9.0.0, v8-to-istanbul@^9.0.1: "@types/istanbul-lib-coverage" "^2.0.1" convert-source-map "^1.6.0" +v8-to-istanbul@^9.0.1: + version "9.1.0" + resolved "https://registry.yarnpkg.com/v8-to-istanbul/-/v8-to-istanbul-9.1.0.tgz#1b83ed4e397f58c85c266a570fc2558b5feb9265" + integrity sha512-6z3GW9x8G1gd+JIIgQQQxXuiJtCXeAjp6RaPEPLv62mH3iPHPxV6W3robxtCzNErRo6ZwTmzWhsbNvjyEBKzKA== + dependencies: + "@jridgewell/trace-mapping" "^0.3.12" + "@types/istanbul-lib-coverage" "^2.0.1" + convert-source-map "^1.6.0" + validate-npm-package-license@^3.0.1: version "3.0.4" resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz#fc91f6b9c7ba15c857f4cb2c5defeec39d4f410a" @@ -7541,9 +7681,9 @@ write-file-atomic@^4.0.2: signal-exit "^3.0.7" ws@^8.11.0: - version "8.12.0" - resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.0.tgz#485074cc392689da78e1828a9ff23585e06cddd8" - integrity sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig== + version "8.12.1" + resolved "https://registry.yarnpkg.com/ws/-/ws-8.12.1.tgz#c51e583d79140b5e42e39be48c934131942d4a8f" + integrity sha512-1qo+M9Ba+xNhPB+YTWUlK6M17brTut5EXbcBaMRN5pH5dFrXz7lzz1ChFSUq3bOUl8yEvSenhHmYUNJxFzdJew== xml-name-validator@^4.0.0: version "4.0.0" @@ -7608,7 +7748,7 @@ yargs@^16.2.0: y18n "^5.0.5" yargs-parser "^20.2.2" -yargs@^17.0.1, yargs@^17.3.1: +yargs@^17.0.1: version "17.6.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.6.2.tgz#2e23f2944e976339a1ee00f18c77fedee8332541" integrity sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw== @@ -7621,6 +7761,19 @@ yargs@^17.0.1, yargs@^17.3.1: y18n "^5.0.5" yargs-parser "^21.1.1" +yargs@^17.3.1: + version "17.7.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" + integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== + dependencies: + cliui "^8.0.1" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.3" + y18n "^5.0.5" + yargs-parser "^21.1.1" + yargs@~3.10.0: version "3.10.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" From d70ffdbc02441764df1e334b55bf77108476aa19 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 22 Feb 2023 17:39:37 +0000 Subject: [PATCH 02/24] Improve types (#3175) * Improve types * Add test --- spec/integ/matrix-client-methods.spec.ts | 11 +++++-- src/@types/IIdentityServerProvider.ts | 2 +- src/client.ts | 41 +++++++++++++----------- src/http-api/fetch.ts | 2 +- 4 files changed, 34 insertions(+), 22 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.ts b/spec/integ/matrix-client-methods.spec.ts index a665aef86e1..21d224150d6 100644 --- a/spec/integ/matrix-client-methods.spec.ts +++ b/spec/integ/matrix-client-methods.spec.ts @@ -1336,18 +1336,25 @@ describe("MatrixClient", function () { it.each([ { userId: "alice@localhost", + powerLevel: 100, expectation: { "alice@localhost": 100, }, }, { userId: ["alice@localhost", "bob@localhost"], + powerLevel: 100, expectation: { "alice@localhost": 100, "bob@localhost": 100, }, }, - ])("should modify power levels of $userId correctly", async ({ userId, expectation }) => { + { + userId: "alice@localhost", + powerLevel: undefined, + expectation: {}, + }, + ])("should modify power levels of $userId correctly", async ({ userId, powerLevel, expectation }) => { const event = { getType: () => "m.room.power_levels", getContent: () => ({ @@ -1364,7 +1371,7 @@ describe("MatrixClient", function () { }) .respond(200, {}); - const prom = client!.setPowerLevel("!room_id:server", userId, 100, event); + const prom = client!.setPowerLevel("!room_id:server", userId, powerLevel, event); await httpBackend!.flushAllExpected(); await prom; }); diff --git a/src/@types/IIdentityServerProvider.ts b/src/@types/IIdentityServerProvider.ts index 05793d53a5d..8e30497409f 100644 --- a/src/@types/IIdentityServerProvider.ts +++ b/src/@types/IIdentityServerProvider.ts @@ -20,5 +20,5 @@ export interface IIdentityServerProvider { * for the associated client. * @returns Promise which resolves to the access token. */ - getAccessToken(): Promise; + getAccessToken(): Promise; } diff --git a/src/client.ts b/src/client.ts index 5ea515fe9e6..d46116675ee 100644 --- a/src/client.ts +++ b/src/client.ts @@ -4130,7 +4130,7 @@ export class MatrixClient extends TypedEventEmitter { let content = { @@ -4141,13 +4141,16 @@ export class MatrixClient extends TypedEventEmitter { - // TODO: Types - const params = { + ): Promise { + const params: Record = { client_secret: clientSecret, email: email, send_attempt: sendAttempt?.toString(), - next_link: nextLink, }; + if (nextLink) { + params.next_link = nextLink; + } - return this.http.idServerRequest( + return this.http.idServerRequest( Method.Post, "/validate/email/requestToken", params, @@ -8788,7 +8792,7 @@ export class MatrixClient extends TypedEventEmitter { - // TODO: Types - const params = { + ): Promise { + const params: Record = { client_secret: clientSecret, country: phoneCountry, phone_number: phoneNumber, send_attempt: sendAttempt?.toString(), - next_link: nextLink, }; + if (nextLink) { + params.next_link = nextLink; + } - return this.http.idServerRequest( + return this.http.idServerRequest( Method.Post, "/validate/msisdn/requestToken", params, diff --git a/src/http-api/fetch.ts b/src/http-api/fetch.ts index 1267fcc7611..ecb09084bd6 100644 --- a/src/http-api/fetch.ts +++ b/src/http-api/fetch.ts @@ -70,7 +70,7 @@ export class FetchHttpApi { this.opts.idBaseUrl = url; } - public idServerRequest>( + public idServerRequest>( method: Method, path: string, params: Record | undefined, From e2e9986059fb943400dd2e24c84bf2245508d45d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Feb 2023 16:43:01 +0000 Subject: [PATCH 03/24] Update babel monorepo to v7.21.0 (#3177) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 173 ++++++++++++++++++++---------------------------------- 1 file changed, 65 insertions(+), 108 deletions(-) diff --git a/yarn.lock b/yarn.lock index 5feb445c29c..5e0297ac715 100644 --- a/yarn.lock +++ b/yarn.lock @@ -27,7 +27,7 @@ dependencies: tunnel "^0.0.6" -"@ampproject/remapping@^2.1.0", "@ampproject/remapping@^2.2.0": +"@ampproject/remapping@^2.2.0": version "2.2.0" resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d" integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w== @@ -36,11 +36,11 @@ "@jridgewell/trace-mapping" "^0.3.9" "@babel/cli@^7.12.10": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.20.7.tgz#8fc12e85c744a1a617680eacb488fab1fcd35b7c" - integrity sha512-WylgcELHB66WwQqItxNILsMlaTd8/SO6SgTTjMp4uCI7P4QyH1r3nqgFmO3BfM4AtfniHgFMH3EpYFj/zynBkQ== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.21.0.tgz#1868eb70e9824b427fc607610cce8e9e7889e7e1" + integrity sha512-xi7CxyS8XjSyiwUGCfwf+brtJxjW1/ZTcBUkP10xawIEXLX5HzLn+3aXkgxozcP2UhRhtKTmQurw9Uaes7jZrA== dependencies: - "@jridgewell/trace-mapping" "^0.3.8" + "@jridgewell/trace-mapping" "^0.3.17" commander "^4.0.1" convert-source-map "^1.1.0" fs-readdir-recursive "^1.1.0" @@ -58,38 +58,17 @@ dependencies: "@babel/highlight" "^7.18.6" -"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.1": - version "7.20.10" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" - integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== - -"@babel/compat-data@^7.20.5": +"@babel/compat-data@^7.17.7", "@babel/compat-data@^7.20.5": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.0.tgz#c241dc454e5b5917e40d37e525e2f4530c399298" integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g== -"@babel/core@^7.0.0", "@babel/core@^7.12.10", "@babel/core@^7.7.5": - version "7.20.12" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.20.12.tgz#7930db57443c6714ad216953d1356dac0eb8496d" - integrity sha512-XsMfHovsUYHFMdrIHkZphTN/2Hzzi78R08NuHfDBehym2VsPDL6Zn/JAD/JQdnRvbSsbQc4mVaU1m6JgtTEElg== - dependencies: - "@ampproject/remapping" "^2.1.0" - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-compilation-targets" "^7.20.7" - "@babel/helper-module-transforms" "^7.20.11" - "@babel/helpers" "^7.20.7" - "@babel/parser" "^7.20.7" - "@babel/template" "^7.20.7" - "@babel/traverse" "^7.20.12" - "@babel/types" "^7.20.7" - convert-source-map "^1.7.0" - debug "^4.1.0" - gensync "^1.0.0-beta.2" - json5 "^2.2.2" - semver "^6.3.0" +"@babel/compat-data@^7.20.1": + version "7.20.10" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.20.10.tgz#9d92fa81b87542fff50e848ed585b4212c1d34ec" + integrity sha512-sEnuDPpOJR/fcafHMjpcpGN5M2jbUGUHwmuWKM/YdPzeEDJg8bgmbcWQFUfE32MQjti1koACvoPVsDe8Uq+idg== -"@babel/core@^7.11.6", "@babel/core@^7.12.3": +"@babel/core@^7.0.0", "@babel/core@^7.11.6", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.0.tgz#1341aefdcc14ccc7553fcc688dd8986a2daffc13" integrity sha512-PuxUbxcW6ZYe656yL3EAhpy7qXKq0DmYsrJLpbB8XrsCP9Nm+XCg9XFMb5vIDliPD7+U/+M+QJlH17XOcB7eXA== @@ -184,6 +163,20 @@ "@babel/helper-replace-supers" "^7.20.7" "@babel/helper-split-export-declaration" "^7.18.6" +"@babel/helper-create-class-features-plugin@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.21.0.tgz#64f49ecb0020532f19b1d014b03bccaa1ab85fb9" + integrity sha512-Q8wNiMIdwsv5la5SPxNYzzkPnjgC0Sy0i7jLkVOCdllu/xcVNkr3TeZzbHBJrj+XXRqzX5uCyCoV9eu6xUG7KQ== + dependencies: + "@babel/helper-annotate-as-pure" "^7.18.6" + "@babel/helper-environment-visitor" "^7.18.9" + "@babel/helper-function-name" "^7.21.0" + "@babel/helper-member-expression-to-functions" "^7.21.0" + "@babel/helper-optimise-call-expression" "^7.18.6" + "@babel/helper-replace-supers" "^7.20.7" + "@babel/helper-skip-transparent-expression-wrappers" "^7.20.0" + "@babel/helper-split-export-declaration" "^7.18.6" + "@babel/helper-create-regexp-features-plugin@^7.18.6", "@babel/helper-create-regexp-features-plugin@^7.20.5": version "7.20.5" resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.20.5.tgz#5ea79b59962a09ec2acf20a963a01ab4d076ccca" @@ -239,12 +232,12 @@ dependencies: "@babel/types" "^7.18.6" -"@babel/helper-member-expression-to-functions@^7.20.7": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.20.7.tgz#a6f26e919582275a93c3aa6594756d71b0bb7f05" - integrity sha512-9J0CxJLq315fEdi4s7xK5TQaNYjZw+nDVpVqr1axNGKzdrdwYBD5b4uKv3n75aABG0rCCTK8Im8Ww7eYfMrZgw== +"@babel/helper-member-expression-to-functions@^7.20.7", "@babel/helper-member-expression-to-functions@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.21.0.tgz#319c6a940431a133897148515877d2f3269c3ba5" + integrity sha512-Muu8cdZwNN6mRRNG6lAYErJ5X3bRevgYR2O8wN0yn7jJSnGDu6eG59RfT29JHxGUovyfrh6Pj0XzmR7drNVL3Q== dependencies: - "@babel/types" "^7.20.7" + "@babel/types" "^7.21.0" "@babel/helper-module-imports@^7.18.6": version "7.18.6" @@ -346,7 +339,7 @@ resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2" integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w== -"@babel/helper-validator-option@^7.18.6": +"@babel/helper-validator-option@^7.18.6", "@babel/helper-validator-option@^7.21.0": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180" integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ== @@ -361,7 +354,7 @@ "@babel/traverse" "^7.20.5" "@babel/types" "^7.20.5" -"@babel/helpers@^7.20.7", "@babel/helpers@^7.21.0": +"@babel/helpers@^7.21.0": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e" integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA== @@ -379,7 +372,7 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.13", "@babel/parser@^7.20.7", "@babel/parser@^7.21.0": +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.20.7", "@babel/parser@^7.21.0": version "7.21.1" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.1.tgz#a8f81ee2fe872af23faea4b17a08fcc869de7bcc" integrity sha512-JzhBFpkuhBNYUY7qs+wTzNmyCWUHEaAFpQQD2YfU1rPL38/L43Wvid0fFkiOCnHvsGncRZgEPyGnltABLcVDTg== @@ -868,12 +861,12 @@ "@babel/helper-plugin-utils" "^7.18.6" "@babel/plugin-transform-runtime@^7.12.10": - version "7.19.6" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.19.6.tgz#9d2a9dbf4e12644d6f46e5e75bfbf02b5d6e9194" - integrity sha512-PRH37lz4JU156lYFW1p8OxE5i7d6Sl/zV58ooyr+q1J1lnQPyg5tIiXlIwNVhJaY4W3TmOtdc8jqdXQcB1v5Yw== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.21.0.tgz#2a884f29556d0a68cd3d152dcc9e6c71dfb6eee8" + integrity sha512-ReY6pxwSzEU0b3r2/T/VhqMKg/AkceBT19X0UptA3/tYi5Pe2eXgEUH+NNMC5nok6c6XQz5tyVTUpuezRfSMSg== dependencies: "@babel/helper-module-imports" "^7.18.6" - "@babel/helper-plugin-utils" "^7.19.0" + "@babel/helper-plugin-utils" "^7.20.2" babel-plugin-polyfill-corejs2 "^0.3.3" babel-plugin-polyfill-corejs3 "^0.6.0" babel-plugin-polyfill-regenerator "^0.4.1" @@ -915,12 +908,12 @@ dependencies: "@babel/helper-plugin-utils" "^7.18.9" -"@babel/plugin-transform-typescript@^7.18.6": - version "7.20.7" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.20.7.tgz#673f49499cd810ae32a1ea5f3f8fab370987e055" - integrity sha512-m3wVKEvf6SoszD8pu4NZz3PvfKRCMgk6D6d0Qi9hNnlM5M6CFS92EgF4EiHVLKbU0r/r7ty1hg7NPZwE7WRbYw== +"@babel/plugin-transform-typescript@^7.21.0": + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typescript/-/plugin-transform-typescript-7.21.0.tgz#f0956a153679e3b377ae5b7f0143427151e4c848" + integrity sha512-xo///XTPp3mDzTtrqXoBlK9eiAYW3wv9JXglcn/u1bi60RW11dEUxIgA8cbnDhutS1zacjMRmAwxE0gMklLnZg== dependencies: - "@babel/helper-create-class-features-plugin" "^7.20.7" + "@babel/helper-create-class-features-plugin" "^7.21.0" "@babel/helper-plugin-utils" "^7.20.2" "@babel/plugin-syntax-typescript" "^7.20.0" @@ -1032,18 +1025,18 @@ esutils "^2.0.2" "@babel/preset-typescript@^7.12.7": - version "7.18.6" - resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.18.6.tgz#ce64be3e63eddc44240c6358daefac17b3186399" - integrity sha512-s9ik86kXBAnD760aybBucdpnLsAt0jK1xqJn2juOn9lkOvSHV60os5hxoVJsPzMQxvnUJFAlkont2DvvaYEBtQ== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.21.0.tgz#bcbbca513e8213691fe5d4b23d9251e01f00ebff" + integrity sha512-myc9mpoVA5m1rF8K8DgLEatOYFDpwC+RkMkjZ0Du6uI62YvDe8uxIEYVs/VCdSJ097nlALiU/yBC7//3nI+hNg== dependencies: - "@babel/helper-plugin-utils" "^7.18.6" - "@babel/helper-validator-option" "^7.18.6" - "@babel/plugin-transform-typescript" "^7.18.6" + "@babel/helper-plugin-utils" "^7.20.2" + "@babel/helper-validator-option" "^7.21.0" + "@babel/plugin-transform-typescript" "^7.21.0" "@babel/register@^7.12.10": - version "7.18.9" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.18.9.tgz#1888b24bc28d5cc41c412feb015e9ff6b96e439c" - integrity sha512-ZlbnXDcNYHMR25ITwwNKT88JiaukkdVj/nG7r3wnuXkOTHc60Uy05PwMCPre0hSkY68E6zK3xz+vUJSP2jWmcw== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.21.0.tgz#c97bf56c2472e063774f31d344c592ebdcefa132" + integrity sha512-9nKsPmYDi5DidAqJaQooxIhsLJiNMkGr8ypQ8Uic7cIox7UCDsM7HuUGxdGT7mSDTYbqzIdsOWzfBton/YJrMw== dependencies: clone-deep "^4.0.1" find-cache-dir "^2.0.0" @@ -1052,9 +1045,9 @@ source-map-support "^0.5.16" "@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.20.13.tgz#7055ab8a7cff2b8f6058bf6ae45ff84ad2aded4b" - integrity sha512-gt3PKXs0DBoL9xCvOIIZ2NEqAGZqHjAnmVbfQtB620V0uReIQutpel14KcneZuer7UioY8ALKZ7iocavvzTNFA== + version "7.21.0" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673" + integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw== dependencies: regenerator-runtime "^0.13.11" @@ -1083,7 +1076,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.12", "@babel/traverse@^7.21.0", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.20.10", "@babel/traverse@^7.20.7", "@babel/traverse@^7.21.0", "@babel/traverse@^7.7.2": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.0.tgz#0e1807abd5db98e6a19c204b80ed1e3f5bca0edc" integrity sha512-Xdt2P1H4LKTO8ApPfnO1KmzYMFpp7D/EinoXzLYN/cHcBNrVCAkAtGUcXnHXrl/VGktureU6fkQrHSBE2URfoA== @@ -1099,23 +1092,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/traverse@^7.20.7": - version "7.20.13" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.20.13.tgz#817c1ba13d11accca89478bd5481b2d168d07473" - integrity sha512-kMJXfF0T6DIS9E8cgdLCSAL+cuCK+YEZHWiLK0SXpTo8YRj5lpJu3CDNKiIBCne4m9hhTIqUg6SYTAI39tAiVQ== - dependencies: - "@babel/code-frame" "^7.18.6" - "@babel/generator" "^7.20.7" - "@babel/helper-environment-visitor" "^7.18.9" - "@babel/helper-function-name" "^7.19.0" - "@babel/helper-hoist-variables" "^7.18.6" - "@babel/helper-split-export-declaration" "^7.18.6" - "@babel/parser" "^7.20.13" - "@babel/types" "^7.20.7" - debug "^4.1.0" - globals "^11.1.0" - -"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": +"@babel/types@^7.0.0", "@babel/types@^7.18.6", "@babel/types@^7.19.0", "@babel/types@^7.20.0", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3": version "7.21.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.0.tgz#1da00d89c2f18b226c9207d96edbeb79316a1819" integrity sha512-uR7NWq2VNFnDi7EYqiRz2Jv/VQIu38tu64Zy8TX2nQFQ6etJ9V/Rr2msW8BS132mum2rL645qpDrLtAJtVpuow== @@ -1124,7 +1101,7 @@ "@babel/helper-validator-identifier" "^7.19.1" to-fast-properties "^2.0.0" -"@babel/types@^7.18.9", "@babel/types@^7.2.0", "@babel/types@^7.20.0", "@babel/types@^7.20.5", "@babel/types@^7.4.4": +"@babel/types@^7.18.9", "@babel/types@^7.2.0", "@babel/types@^7.20.5", "@babel/types@^7.4.4": version "7.20.7" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.20.7.tgz#54ec75e252318423fc07fb644dc6a58a64c09b7f" integrity sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg== @@ -1497,7 +1474,7 @@ resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24" integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw== -"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.8", "@jridgewell/trace-mapping@^0.3.9": +"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.15", "@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9": version "0.3.17" resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985" integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g== @@ -2647,7 +2624,7 @@ browserify@^17.0.0: vm-browserify "^1.0.0" xtend "^4.0.0" -browserslist@^4.21.3: +browserslist@^4.21.3, browserslist@^4.21.5: version "4.21.5" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7" integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w== @@ -2657,16 +2634,6 @@ browserslist@^4.21.3: node-releases "^2.0.8" update-browserslist-db "^1.0.10" -browserslist@^4.21.4: - version "4.21.4" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.4.tgz#e7496bbc67b9e39dd0f98565feccdcb0d4ff6987" - integrity sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw== - dependencies: - caniuse-lite "^1.0.30001400" - electron-to-chromium "^1.4.251" - node-releases "^2.0.6" - update-browserslist-db "^1.0.9" - bs58@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/bs58/-/bs58-5.0.0.tgz#865575b4d13c09ea2a84622df6c8cbeb54ffc279" @@ -2760,11 +2727,6 @@ camelcase@^6.2.0: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== -caniuse-lite@^1.0.30001400: - version "1.0.30001451" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001451.tgz#2e197c698fc1373d63e1406d6607ea4617c613f1" - integrity sha512-XY7UbUpGRatZzoRft//5xOa69/1iGJRBlrieH6QYrkKLIFn3m7OVEJ81dSrKoy2BnKsdbX5cLrOispZNYo9v2w== - caniuse-lite@^1.0.30001449: version "1.0.30001457" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001457.tgz#6af34bb5d720074e2099432aa522c21555a18301" @@ -3033,11 +2995,11 @@ convert-source-map@~1.1.0: integrity sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg== core-js-compat@^3.25.1: - version "3.27.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.27.1.tgz#b5695eb25c602d72b1d30cbfba3cb7e5e4cf0a67" - integrity sha512-Dg91JFeCDA17FKnneN7oCMz4BkQ4TcffkgHP4OWwp9yx3pi7ubqMDXXSacfNak1PQqjc95skyt+YBLHQJnkJwA== + version "3.28.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.28.0.tgz#c08456d854608a7264530a2afa281fadf20ecee6" + integrity sha512-myzPgE7QodMg4nnd3K1TDoES/nADRStM8Gpz0D6nhkwbmwEnE0ZGJgoWsvQ722FR8D7xS0n0LV556RcEicjTyg== dependencies: - browserslist "^4.21.4" + browserslist "^4.21.5" core-js@^2.4.0: version "2.6.12" @@ -3337,11 +3299,6 @@ duplexer2@^0.1.2, duplexer2@~0.1.0, duplexer2@~0.1.2: dependencies: readable-stream "^2.0.2" -electron-to-chromium@^1.4.251: - version "1.4.292" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.292.tgz#e3a3dca3780c8ce01e2c1866b5ec2fbe31c423e3" - integrity sha512-ESWOSyJy5odDlE8wvh5NNAMORv4r6assPwIPGHEMWrWD0SONXcG/xT+9aD9CQyeRwyYDPo6dJT4Bbeg5uevVQQ== - electron-to-chromium@^1.4.284: version "1.4.305" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.305.tgz#e4dfe3e06ab783f33171f9bde9e8ed092510fcd0" @@ -5729,7 +5686,7 @@ node-int64@^0.4.0: resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" integrity sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw== -node-releases@^2.0.6, node-releases@^2.0.8: +node-releases@^2.0.8: version "2.0.10" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f" integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w== @@ -7384,7 +7341,7 @@ universalify@^0.2.0: resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.2.0.tgz#6451760566fa857534745ab1dde952d1b1761be0" integrity sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg== -update-browserslist-db@^1.0.10, update-browserslist-db@^1.0.9: +update-browserslist-db@^1.0.10: version "1.0.10" resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3" integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ== From aec1c110379474e706518fc630a5e87ce21b2684 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 24 Feb 2023 12:17:19 +0000 Subject: [PATCH 04/24] Update all non-major dependencies (#3171) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/docs-pr-netlify.yaml | 2 +- package.json | 4 +- yarn.lock | 76 ++++++++++++++------------ 3 files changed, 44 insertions(+), 38 deletions(-) diff --git a/.github/workflows/docs-pr-netlify.yaml b/.github/workflows/docs-pr-netlify.yaml index b5d28971740..903ad2a4226 100644 --- a/.github/workflows/docs-pr-netlify.yaml +++ b/.github/workflows/docs-pr-netlify.yaml @@ -14,7 +14,7 @@ jobs: # There's a 'download artifact' action, but it hasn't been updated for the workflow_run action # (https://github.com/actions/download-artifact/issues/60) so instead we get this mess: - name: 📥 Download artifact - uses: dawidd6/action-download-artifact@bd10f381a96414ce2b13a11bfa89902ba7cea07f # v2.24.3 + uses: dawidd6/action-download-artifact@5e780fc7bbd0cac69fc73271ed86edf5dcb72d67 # v2.26.0 with: workflow: static_analysis.yml run_id: ${{ github.event.workflow_run.id }} diff --git a/package.json b/package.json index 207d361a959..590ce726feb 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,7 @@ "debug": "^4.3.4", "docdash": "^2.0.0", "domexception": "^4.0.0", - "eslint": "8.33.0", + "eslint": "8.34.0", "eslint-config-google": "^0.14.0", "eslint-config-prettier": "^8.5.0", "eslint-import-resolver-typescript": "^3.5.1", @@ -118,7 +118,7 @@ "jest-localstorage-mock": "^2.4.6", "jest-mock": "^29.0.0", "matrix-mock-request": "^2.5.0", - "prettier": "2.8.3", + "prettier": "2.8.4", "rimraf": "^4.0.0", "terser": "^5.5.1", "tsify": "^5.0.2", diff --git a/yarn.lock b/yarn.lock index 5e0297ac715..9f99a9e137f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2160,6 +2160,11 @@ ansi-regex@^5.0.1: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== +ansi-sequence-parser@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/ansi-sequence-parser/-/ansi-sequence-parser-1.1.0.tgz#4d790f31236ac20366b23b3916b789e1bde39aed" + integrity sha512-lEm8mt52to2fT8GhciPCGeCXACSz2UwIN4X2e2LJSnZ5uAbn2/dsYdOmUXq0AtWS5cpAupysIneExOgH0Vd2TQ== + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -3547,9 +3552,9 @@ eslint-plugin-jest@^27.1.6: "@typescript-eslint/utils" "^5.10.0" eslint-plugin-jsdoc@^39.6.4: - version "39.8.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.8.0.tgz#9ca38ae31fb6e6de6268c5c041fa175fe1190469" - integrity sha512-ZwGmk0jJoJD/NILeDRBKrpq/PCgddUdATjeU5JGTqTzKsOWfeaHOnaAwZjuOh7T8EB4hSoZ/9pR4+Qns2ldQVg== + version "39.9.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.9.1.tgz#e9ce1723411fd7ea0933b3ef0dd02156ae3068e2" + integrity sha512-Rq2QY6BZP2meNIs48aZ3GlIlJgBqFCmR55+UBvaDkA3ZNQ0SvQXOs2QKkubakEijV8UbIVbVZKsOVN8G3MuqZw== dependencies: "@es-joy/jsdoccomment" "~0.36.1" comment-parser "1.3.1" @@ -3632,10 +3637,10 @@ eslint-visitor-keys@^3.3.0: resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz#f6480fa6b1f30efe2d1968aa8ac745b862469826" integrity sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA== -eslint@8.33.0: - version "8.33.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.33.0.tgz#02f110f32998cb598c6461f24f4d306e41ca33d7" - integrity sha512-WjOpFQgKK8VrCnAtl8We0SUOy/oVZ5NHykyMiagV1M9r8IFpIJX7DduK6n1mpfhlG7T1NLWm2SuD8QB7KFySaA== +eslint@8.34.0: + version "8.34.0" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-8.34.0.tgz#fe0ab0ef478104c1f9ebc5537e303d25a8fb22d6" + integrity sha512-1Z8iFsucw+7kSqXNZVslXS8Ioa4u2KM7GPwuKtkTFAqZ/cHMcEaR+1+Br0wLlot49cNxIiZk5wp8EAbPcYZxTg== dependencies: "@eslint/eslintrc" "^1.4.1" "@humanwhocodes/config-array" "^0.11.8" @@ -3692,9 +3697,9 @@ esprima@^4.0.0, esprima@^4.0.1, esprima@~4.0.0: integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== esquery@^1.4.0: - version "1.4.0" - resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.0.tgz#2148ffc38b82e8c7057dfed48425b3e61f0f24a5" - integrity sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w== + version "1.4.2" + resolved "https://registry.yarnpkg.com/esquery/-/esquery-1.4.2.tgz#c6d3fee05dd665808e2ad870631f221f5617b1d1" + integrity sha512-JVSoLdTlTDkmjFmab7H/9SL9qGSyjElT3myyKp7krqjVFQCDLmj1QFaCLRFBszBKI0XVZaiiXvuPIX3ZwHe1Ng== dependencies: estraverse "^5.1.0" @@ -5473,10 +5478,10 @@ makeerror@1.0.12: dependencies: tmpl "1.0.5" -marked@^4.2.5: - version "4.2.5" - resolved "https://registry.yarnpkg.com/marked/-/marked-4.2.5.tgz#979813dfc1252cc123a79b71b095759a32f42a5d" - integrity sha512-jPueVhumq7idETHkb203WDD4fMA3yV9emQ5vLwop58lu8bTclMghBWcYAavlDqIEMaisADinV1TooIFCfqOsYQ== +marked@^4.2.12: + version "4.2.12" + resolved "https://registry.yarnpkg.com/marked/-/marked-4.2.12.tgz#d69a64e21d71b06250da995dcd065c11083bebb5" + integrity sha512-yr8hSKa3Fv4D3jdZmtMMPghgVt6TWbk86WQaWhDloQjRSQhMMYCAro7jP7VDJrjjdV8pxVxMssXS8B8Y5DZ5aw== matrix-events-sdk@0.0.1: version "0.0.1" @@ -5586,10 +5591,10 @@ minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatc dependencies: brace-expansion "^1.1.7" -minimatch@^5.1.2: - version "5.1.2" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.2.tgz#0939d7d6f0898acbd1508abe534d1929368a8fff" - integrity sha512-bNH9mmM9qsJ2X4r2Nat1B//1dJVcn3+iBLa3IgqJ7EbGaDNepL9QSHOxN4ng33s52VMMhhIfgCYDk3C4ZmlDAg== +minimatch@^6.1.6: + version "6.2.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-6.2.0.tgz#2b70fd13294178c69c04dfc05aebdb97a4e79e42" + integrity sha512-sauLxniAmvnhhRjFwPNnJKaPFYyddAgbYdeUpHULtCT/GhzdCx/MDNy+Y40lBxTQUrMzDE8e0S43Z5uqfO0REg== dependencies: brace-expansion "^2.0.1" @@ -6011,10 +6016,10 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w== -prettier@2.8.3: - version "2.8.3" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.3.tgz#ab697b1d3dd46fb4626fbe2f543afe0cc98d8632" - integrity sha512-tJ/oJ4amDihPoufT5sM0Z1SKEuKay8LfVAMlbbhnnkvt6BUserZylqo2PN+p9KeljLr0OHa2rXHU1T8reeoTrw== +prettier@2.8.4: + version "2.8.4" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.8.4.tgz#34dd2595629bfbb79d344ac4a91ff948694463c3" + integrity sha512-vIS4Rlc2FNh0BySk3Wkd6xmwxB0FpOndW5fisM5H8hsZSxU2VWVB5CWIkIjWvrHjIhxk2g3bfMKM87zNTrZddw== pretty-format@^28.1.3: version "28.1.3" @@ -6664,11 +6669,12 @@ shell-quote@^1.6.1: resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.7.4.tgz#33fe15dee71ab2a81fcbd3a52106c5cfb9fb75d8" integrity sha512-8o/QEhSSRb1a5i7TFR0iM4G16Z0vYB2OQVs4G3aAFXjn3T6yEx8AZxy1PgDF7I00LZHYA3WxaSYIf5e5sAX8Rw== -shiki@^0.12.1: - version "0.12.1" - resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.12.1.tgz#26fce51da12d055f479a091a5307470786f300cd" - integrity sha512-aieaV1m349rZINEBkjxh2QbBvFFQOlgqYTNtCal82hHj4dDZ76oMlQIX+C7ryerBTDiga3e5NfH6smjdJ02BbQ== +shiki@^0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.14.1.tgz#9fbe082d0a8aa2ad63df4fbf2ee11ec924aa7ee1" + integrity sha512-+Jz4nBkCBe0mEDqo1eKRcCdjRtrCjozmcbTUjbPTX7OOJfEbTZzlUWlZtGe3Gb5oV1/jnojhG//YZc3rs9zSEw== dependencies: + ansi-sequence-parser "^1.1.0" jsonc-parser "^3.2.0" vscode-oniguruma "^1.7.0" vscode-textmate "^8.0.0" @@ -6964,9 +6970,9 @@ tapable@^2.2.0: integrity sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ== terser@^5.5.1: - version "5.16.3" - resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.3.tgz#3266017a9b682edfe019b8ecddd2abaae7b39c6b" - integrity sha512-v8wWLaS/xt3nE9dgKEWhNUFP6q4kngO5B8eYFUuebsu7Dw/UNAnpUod6UHo04jSSkv8TzKHjZDSd7EXdDQAl8Q== + version "5.16.5" + resolved "https://registry.yarnpkg.com/terser/-/terser-5.16.5.tgz#1c285ca0655f467f92af1bbab46ab72d1cb08e5a" + integrity sha512-qcwfg4+RZa3YvlFh0qjifnzBHjKGNbtDo9yivMqMFDy9Q6FSaQWSB/j1xKhsoUFJIqDOM3TsN6D5xbrMrFcHbg== dependencies: "@jridgewell/source-map" "^0.3.2" acorn "^8.5.0" @@ -7224,14 +7230,14 @@ typedoc-plugin-missing-exports@^1.0.0: integrity sha512-7s6znXnuAj1eD9KYPyzVzR1lBF5nwAY8IKccP5sdoO9crG4lpd16RoFpLsh2PccJM+I2NASpr0+/NMka6ThwVA== typedoc@^0.23.20: - version "0.23.24" - resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.24.tgz#01cf32c09f2c19362e72a9ce1552d6e5b48c4fef" - integrity sha512-bfmy8lNQh+WrPYcJbtjQ6JEEsVl/ce1ZIXyXhyW+a1vFrjO39t6J8sL/d6FfAGrJTc7McCXgk9AanYBSNvLdIA== + version "0.23.25" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.25.tgz#5f8f1850fd044c4d15d453117affddf11a265610" + integrity sha512-O1he153qVyoCgJYSvIyY3bPP1wAJTegZfa6tL3APinSZhJOf8CSd8F/21M6ex8pUY/fuY6n0jAsT4fIuMGA6sA== dependencies: lunr "^2.3.9" - marked "^4.2.5" - minimatch "^5.1.2" - shiki "^0.12.1" + marked "^4.2.12" + minimatch "^6.1.6" + shiki "^0.14.1" typescript@^3.2.2: version "3.9.10" From 9c8093eb3e140385c8f1a5763e0c0a099584238b Mon Sep 17 00:00:00 2001 From: Janne Mareike Koschinski Date: Fri, 24 Feb 2023 14:12:06 +0100 Subject: [PATCH 05/24] Fix reactions in threads sometimes causing stuck notifications (#3146) * Associate event with thread before adding it to the thread timeline * Make sure events can be added to thread correctly * Write initial test case * Add additional comment for why the code had to be reordered --- ...matrix-client-unread-notifications.spec.ts | 95 ++++++++++++++++++- src/models/room.ts | 9 +- 2 files changed, 101 insertions(+), 3 deletions(-) diff --git a/spec/integ/matrix-client-unread-notifications.spec.ts b/spec/integ/matrix-client-unread-notifications.spec.ts index d65478ed84e..8274d7afaba 100644 --- a/spec/integ/matrix-client-unread-notifications.spec.ts +++ b/spec/integ/matrix-client-unread-notifications.spec.ts @@ -18,8 +18,21 @@ import "fake-indexeddb/auto"; import HttpBackend from "matrix-mock-request"; -import { Category, ISyncResponse, MatrixClient, NotificationCountType, Room } from "../../src"; +import { + Category, + ClientEvent, + EventType, + ISyncResponse, + MatrixClient, + MatrixEvent, + NotificationCountType, + RelationType, + Room, +} from "../../src"; import { TestClient } from "../TestClient"; +import { ReceiptType } from "../../src/@types/read_receipts"; +import { mkThread } from "../test-utils/thread"; +import { SyncState } from "../../src/sync"; describe("MatrixClient syncing", () => { const userA = "@alice:localhost"; @@ -51,6 +64,86 @@ describe("MatrixClient syncing", () => { return httpBackend!.stop(); }); + it("reactions in thread set the correct timeline to unread", async () => { + const roomId = "!room:localhost"; + + // start the client, and wait for it to initialise + httpBackend!.when("GET", "/sync").respond(200, { + next_batch: "s_5_3", + rooms: { + [Category.Join]: {}, + [Category.Leave]: {}, + [Category.Invite]: {}, + }, + }); + client!.startClient({ threadSupport: true }); + await Promise.all([ + httpBackend?.flushAllExpected(), + new Promise((resolve) => { + client!.on(ClientEvent.Sync, (state) => state === SyncState.Syncing && resolve()); + }), + ]); + + const room = new Room(roomId, client!, selfUserId); + jest.spyOn(client!, "getRoom").mockImplementation((id) => (id === roomId ? room : null)); + + const thread = mkThread({ room, client: client!, authorId: selfUserId, participantUserIds: [selfUserId] }); + const threadReply = thread.events.at(-1)!; + room.addLiveEvents([thread.rootEvent]); + + // Initialize read receipt datastructure before testing the reaction + room.addReceiptToStructure(thread.rootEvent.getId()!, ReceiptType.Read, selfUserId, { ts: 1 }, false); + thread.thread.addReceiptToStructure( + threadReply.getId()!, + ReceiptType.Read, + selfUserId, + { thread_id: thread.thread.id, ts: 1 }, + false, + ); + expect(room.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(thread.rootEvent.getId()); + expect(thread.thread.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(threadReply.getId()); + + const reactionEventId = `$9-${Math.random()}-${Math.random()}`; + let lastEvent: MatrixEvent | null = null; + jest.spyOn(client! as any, "sendEventHttpRequest").mockImplementation((event) => { + lastEvent = event as MatrixEvent; + return { event_id: reactionEventId }; + }); + + await client!.sendEvent(roomId, EventType.Reaction, { + "m.relates_to": { + rel_type: RelationType.Annotation, + event_id: threadReply.getId(), + key: "", + }, + }); + + expect(lastEvent!.getId()).toEqual(reactionEventId); + room.handleRemoteEcho(new MatrixEvent(lastEvent!.event), lastEvent!); + + // Our ideal state after this is the following: + // + // Room: [synthetic: threadroot, actual: threadroot] + // Thread: [synthetic: threadreaction, actual: threadreply] + // + // The reaction and reply are both in the thread, and their receipts should be isolated to the thread. + // The reaction has not been acknowledged in a dedicated read receipt message, so only the synthetic receipt + // should be updated. + + // Ensure the synthetic receipt for the room has not been updated + expect(room.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(thread.rootEvent.getId()); + expect(room.getEventReadUpTo(selfUserId, false)).toEqual(thread.rootEvent.getId()); + // Ensure the actual receipt for the room has not been updated + expect(room.getReadReceiptForUserId(selfUserId, true)?.eventId).toEqual(thread.rootEvent.getId()); + expect(room.getEventReadUpTo(selfUserId, true)).toEqual(thread.rootEvent.getId()); + // Ensure the synthetic receipt for the thread has been updated + expect(thread.thread.getReadReceiptForUserId(selfUserId, false)?.eventId).toEqual(reactionEventId); + expect(thread.thread.getEventReadUpTo(selfUserId, false)).toEqual(reactionEventId); + // Ensure the actual receipt for the thread has not been updated + expect(thread.thread.getReadReceiptForUserId(selfUserId, true)?.eventId).toEqual(threadReply.getId()); + expect(thread.thread.getEventReadUpTo(selfUserId, true)).toEqual(threadReply.getId()); + }); + describe("Stuck unread notifications integration tests", () => { const ROOM_ID = "!room:localhost"; diff --git a/src/models/room.ts b/src/models/room.ts index 93bdb99a759..399f9861437 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -2151,14 +2151,17 @@ export class Room extends ReadReceipt { // a reference to the cached receipts anymore. this.cachedThreadReadReceipts.delete(threadId); + // If we managed to create a thread and figure out its `id` then we can use it + // This has to happen before thread.addEvents, because that adds events to the eventtimeline, and the + // eventtimeline sometimes looks up thread information via the room. + this.threads.set(thread.id, thread); + // This is necessary to be able to jump to events in threads: // If we jump to an event in a thread where neither the event, nor the root, // nor any thread event are loaded yet, we'll load the event as well as the thread root, create the thread, // and pass the event through this. thread.addEvents(events, false); - // If we managed to create a thread and figure out its `id` then we can use it - this.threads.set(thread.id, thread); this.reEmitter.reEmit(thread, [ ThreadEvent.Delete, ThreadEvent.Update, @@ -2467,6 +2470,7 @@ export class Room extends ReadReceipt { const { shouldLiveInRoom, threadId } = this.eventShouldLiveIn(remoteEvent); const thread = threadId ? this.getThread(threadId) : null; + thread?.setEventMetadata(localEvent); thread?.timelineSet.handleRemoteEcho(localEvent, oldEventId, newEventId); if (shouldLiveInRoom) { @@ -2548,6 +2552,7 @@ export class Room extends ReadReceipt { const { shouldLiveInRoom, threadId } = this.eventShouldLiveIn(event); const thread = threadId ? this.getThread(threadId) : undefined; + thread?.setEventMetadata(event); thread?.timelineSet.replaceEventId(oldEventId, newEventId!); if (shouldLiveInRoom) { From d80b7499fd99f202a9c819dd03baca965fc76936 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michael=20Telaty=C5=84ski?= <7t3chguy@gmail.com> Date: Mon, 27 Feb 2023 22:12:45 +0000 Subject: [PATCH 06/24] Fix spec compliance issue around encrypted `m.relates_to` (#3178) * Fix spec compliance issue around encrypted `m.relates_to` * Add test --- spec/unit/models/event.spec.ts | 36 +++++++++++++++++++++++++++++++++- src/models/event.ts | 8 +------- 2 files changed, 36 insertions(+), 8 deletions(-) diff --git a/spec/unit/models/event.spec.ts b/spec/unit/models/event.spec.ts index dd21893a52c..85058a56b83 100644 --- a/spec/unit/models/event.spec.ts +++ b/spec/unit/models/event.spec.ts @@ -16,7 +16,7 @@ limitations under the License. import { MatrixEvent, MatrixEventEvent } from "../../../src/models/event"; import { emitPromise } from "../../test-utils/test-utils"; -import { Crypto } from "../../../src/crypto"; +import { Crypto, IEventDecryptionResult } from "../../../src/crypto"; describe("MatrixEvent", () => { it("should create copies of itself", () => { @@ -182,4 +182,38 @@ describe("MatrixEvent", () => { expect(encryptedEvent.getType()).toEqual("m.room.message"); }); }); + + describe("replyEventId", () => { + it("should ignore 'm.relates_to' from encrypted content even if cleartext lacks one", async () => { + const eventId = "test_encrypted_event"; + const encryptedEvent = new MatrixEvent({ + event_id: eventId, + type: "m.room.encrypted", + content: { + ciphertext: "secrets", + }, + }); + + const crypto = { + decryptEvent: jest.fn().mockImplementationOnce(() => { + return Promise.resolve({ + clearEvent: { + type: "m.room.message", + content: { + "m.relates_to": { + "m.in_reply_to": { + event_id: "!anotherEvent", + }, + }, + }, + }, + }); + }), + } as unknown as Crypto; + + await encryptedEvent.attemptDecryption(crypto); + expect(encryptedEvent.getType()).toEqual("m.room.message"); + expect(encryptedEvent.replyEventId).toBeUndefined(); + }); + }); }); diff --git a/src/models/event.ts b/src/models/event.ts index d4baa5b224b..d6623ae3f97 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -576,13 +576,7 @@ export class MatrixEvent extends TypedEventEmitter Date: Tue, 28 Feb 2023 10:37:23 +0000 Subject: [PATCH 07/24] Resetting package fields for development --- package.json | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d65dbeee842..33abb311bae 100644 --- a/package.json +++ b/package.json @@ -32,8 +32,8 @@ "keywords": [ "matrix-org" ], - "main": "./lib/index.js", - "browser": "./lib/browser-index.js", + "main": "./src/index.ts", + "browser": "./src/browser-index.ts", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.ts", "matrix_lib_main": "./lib/index.js", @@ -147,6 +147,5 @@ "outputDirectory": "coverage", "outputName": "jest-sonar-report.xml", "relativePaths": true - }, - "typings": "./lib/index.d.ts" + } } From c8a4d9b88a0bd81be7cd266906da3d3554710603 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Wed, 1 Mar 2023 07:23:40 -0500 Subject: [PATCH 08/24] Implement MSC3873 to handle escaped dots in push rule keys (#3134) * Add comments. * Implment MSC3873 to handle escaped dots in keys. * Add some comments about tests. * Clarify spec behavior. * Fix typo. * Don't manually iterate string. * Clean-up tests. * Simplify tests. * Add more tests & fix bug with empty parts. * Add more edge cases. * Add a regular expression solution. This is ~80% slower than the basic split("."). * Split on a simpler regular expression. This is ~50% slower than a simple split("."). * Remove redundant case in regex. * Enable sticky regex. * Rollback use of regex. * Cache values in the PushProcessor. * Use more each in tests. * Pre-calculate the key parts instead of caching them. * Fix typo. * Switch back to external cache, but clean out obsolete cached values. * Remove obsolete property. * Remove more obsolete properties. --- spec/unit/pushprocessor.spec.ts | 91 ++++++++++++++++++++- src/client.ts | 14 +++- src/pushprocessor.ts | 139 ++++++++++++++++++++++++++++++-- src/sliding-sync-sdk.ts | 3 +- src/sync.ts | 3 +- 5 files changed, 238 insertions(+), 12 deletions(-) diff --git a/spec/unit/pushprocessor.spec.ts b/spec/unit/pushprocessor.spec.ts index dd84f03820a..f43d5f8aa6c 100644 --- a/spec/unit/pushprocessor.spec.ts +++ b/spec/unit/pushprocessor.spec.ts @@ -1,6 +1,6 @@ import * as utils from "../test-utils/test-utils"; import { IActionsObject, PushProcessor } from "../../src/pushprocessor"; -import { EventType, IContent, MatrixClient, MatrixEvent } from "../../src"; +import { ConditionKind, EventType, IContent, MatrixClient, MatrixEvent } from "../../src"; describe("NotificationService", function () { const testUserId = "@ali:matrix.org"; @@ -287,6 +287,13 @@ describe("NotificationService", function () { expect(actions.tweaks.highlight).toEqual(true); }); + // TODO: This is not spec compliant behaviour. + // + // See https://spec.matrix.org/v1.5/client-server-api/#conditions-1 which + // describes pattern should glob: + // + // 1. * matches 0 or more characters; + // 2. ? matches exactly one character it("should bing on character group ([abc]) bing words.", function () { testEvent.event.content!.body = "Ping!"; let actions = pushProcessor.actionsForEvent(testEvent); @@ -296,12 +303,14 @@ describe("NotificationService", function () { expect(actions.tweaks.highlight).toEqual(true); }); + // TODO: This is not spec compliant behaviour. (See above.) it("should bing on character range ([a-z]) bing words.", function () { testEvent.event.content!.body = "I ate 6 pies"; const actions = pushProcessor.actionsForEvent(testEvent); expect(actions.tweaks.highlight).toEqual(true); }); + // TODO: This is not spec compliant behaviour. (See above.) it("should bing on character negation ([!a]) bing words.", function () { testEvent.event.content!.body = "boke"; let actions = pushProcessor.actionsForEvent(testEvent); @@ -330,6 +339,8 @@ describe("NotificationService", function () { // invalid it("should gracefully handle bad input.", function () { + // The following body is an object (not a string) and thus is invalid + // for matching against. testEvent.event.content!.body = { foo: "bar" }; const actions = pushProcessor.actionsForEvent(testEvent); expect(actions.tweaks.highlight).toEqual(false); @@ -493,4 +504,82 @@ describe("NotificationService", function () { }); }); }); + + it.each([ + // The properly escaped key works. + { key: "content.m\\.test.foo", pattern: "bar", expected: true }, + // An unescaped version does not match. + { key: "content.m.test.foo", pattern: "bar", expected: false }, + // Over escaping does not match. + { key: "content.m\\.test\\.foo", pattern: "bar", expected: false }, + // Escaping backslashes should match. + { key: "content.m\\\\example", pattern: "baz", expected: true }, + // An unnecessary escape sequence leaves the backslash and still matches. + { key: "content.m\\example", pattern: "baz", expected: true }, + ])("test against escaped dotted paths '$key'", ({ key, pattern, expected }) => { + testEvent = utils.mkEvent({ + type: "m.room.message", + room: testRoomId, + user: "@alfred:localhost", + event: true, + content: { + // A dot in the field name. + "m.test": { foo: "bar" }, + // A backslash in a field name. + "m\\example": "baz", + }, + }); + + expect( + pushProcessor.ruleMatchesEvent( + { + rule_id: "rule1", + actions: [], + conditions: [ + { + kind: ConditionKind.EventMatch, + key: key, + pattern: pattern, + }, + ], + default: false, + enabled: true, + }, + testEvent, + ), + ).toBe(expected); + }); +}); + +describe("Test PushProcessor.partsForDottedKey", function () { + it.each([ + // A field with no dots. + ["m", ["m"]], + // Simple dotted fields. + ["m.foo", ["m", "foo"]], + ["m.foo.bar", ["m", "foo", "bar"]], + // Backslash is used as an escape character. + ["m\\.foo", ["m.foo"]], + ["m\\\\.foo", ["m\\", "foo"]], + ["m\\\\\\.foo", ["m\\.foo"]], + ["m\\\\\\\\.foo", ["m\\\\", "foo"]], + ["m\\foo", ["m\\foo"]], + ["m\\\\foo", ["m\\foo"]], + ["m\\\\\\foo", ["m\\\\foo"]], + ["m\\\\\\\\foo", ["m\\\\foo"]], + // Ensure that escapes at the end don't cause issues. + ["m.foo\\", ["m", "foo\\"]], + ["m.foo\\\\", ["m", "foo\\"]], + ["m.foo\\.", ["m", "foo."]], + ["m.foo\\\\.", ["m", "foo\\", ""]], + ["m.foo\\\\\\.", ["m", "foo\\."]], + // Empty parts (corresponding to properties which are an empty string) are allowed. + [".m", ["", "m"]], + ["..m", ["", "", "m"]], + ["m.", ["m", ""]], + ["m..", ["m", "", ""]], + ["m..foo", ["m", "", "foo"]], + ])("partsFotDottedKey for %s", (path: string, expected: string[]) => { + expect(PushProcessor.partsForDottedKey(path)).toStrictEqual(expected); + }); }); diff --git a/src/client.ts b/src/client.ts index d46116675ee..d59f5cc5d68 100644 --- a/src/client.ts +++ b/src/client.ts @@ -8499,10 +8499,22 @@ export class MatrixClient extends TypedEventEmitter { return this.http.authedRequest(Method.Get, "/pushrules/").then((rules: IPushRules) => { - return PushProcessor.rewriteDefaultRules(rules); + this.setPushRules(rules); + return this.pushRules!; }); } + /** + * Update the push rules for the account. This should be called whenever + * updated push rules are available. + */ + public setPushRules(rules: IPushRules): void { + // Fix-up defaults, if applicable. + this.pushRules = PushProcessor.rewriteDefaultRules(rules); + // Pre-calculate any necessary caches. + this.pushProcessor.updateCachedPushRuleKeys(this.pushRules); + } + /** * @returns Promise which resolves: an empty object `{}` * @returns Rejects: with an error response. diff --git a/src/pushprocessor.ts b/src/pushprocessor.ts index 0d7338f8fb1..2bbf8fbdb9c 100644 --- a/src/pushprocessor.ts +++ b/src/pushprocessor.ts @@ -123,6 +123,12 @@ export class PushProcessor { */ public constructor(private readonly client: MatrixClient) {} + /** + * Maps the original key from the push rules to a list of property names + * after unescaping. + */ + private readonly parsedKeys = new Map(); + /** * Convert a list of actions into a object with the actions as keys and their values * @example @@ -162,7 +168,7 @@ export class PushProcessor { if (!newRules) newRules = {} as IPushRules; if (!newRules.global) newRules.global = {} as PushRuleSet; if (!newRules.global.override) newRules.global.override = []; - if (!newRules.global.override) newRules.global.underride = []; + if (!newRules.global.underride) newRules.global.underride = []; // Merge the client-level defaults with the ones from the server const globalOverrides = newRules.global.override; @@ -202,6 +208,53 @@ export class PushProcessor { return newRules; } + /** + * Pre-caches the parsed keys for push rules and cleans out any obsolete cache + * entries. Should be called after push rules are updated. + * @param newRules - The new push rules. + */ + public updateCachedPushRuleKeys(newRules: IPushRules): void { + // These lines are mostly to make the tests happy. We shouldn't run into these + // properties missing in practice. + if (!newRules) newRules = {} as IPushRules; + if (!newRules.global) newRules.global = {} as PushRuleSet; + if (!newRules.global.override) newRules.global.override = []; + if (!newRules.global.room) newRules.global.room = []; + if (!newRules.global.sender) newRules.global.sender = []; + if (!newRules.global.underride) newRules.global.underride = []; + + // Process the 'key' property on event_match conditions pre-cache the + // values and clean-out any unused values. + const toRemoveKeys = new Set(this.parsedKeys.keys()); + for (const ruleset of [ + newRules.global.override, + newRules.global.room, + newRules.global.sender, + newRules.global.underride, + ]) { + for (const rule of ruleset) { + if (!rule.conditions) { + continue; + } + + for (const condition of rule.conditions) { + if (condition.kind !== ConditionKind.EventMatch) { + continue; + } + + // Ensure we keep this key. + toRemoveKeys.delete(condition.key); + + // Pre-process the key. + this.parsedKeys.set(condition.key, PushProcessor.partsForDottedKey(condition.key)); + } + } + } + // Any keys that were previously cached, but are no longer needed should + // be removed. + toRemoveKeys.forEach((k) => this.parsedKeys.delete(k)); + } + private static cachedGlobToRegex: Record = {}; // $glob: RegExp private matchingRuleFromKindSet(ev: MatrixEvent, kindset: PushRuleSet): IAnnotatedPushRule | null { @@ -433,25 +486,99 @@ export class PushProcessor { return PushProcessor.cachedGlobToRegex[glob]; } + /** + * Parse the key into the separate fields to search by splitting on + * unescaped ".", and then removing any escape characters. + * + * @param str - The key of the push rule condition: a dotted field. + * @returns The unescaped parts to fetch. + * @internal + */ + public static partsForDottedKey(str: string): string[] { + const result = []; + + // The current field and whether the previous character was the escape + // character (a backslash). + let part = ""; + let escaped = false; + + // Iterate over each character, and decide whether to append to the current + // part (following the escape rules) or to start a new part (based on the + // field separator). + for (const c of str) { + // If the previous character was the escape character (a backslash) + // then decide what to append to the current part. + if (escaped) { + if (c === "\\" || c === ".") { + // An escaped backslash or dot just gets added. + part += c; + } else { + // A character that shouldn't be escaped gets the backslash prepended. + part += "\\" + c; + } + // This always resets being escaped. + escaped = false; + continue; + } + + if (c == ".") { + // The field separator creates a new part. + result.push(part); + part = ""; + } else if (c == "\\") { + // A backslash adds no characters, but starts an escape sequence. + escaped = true; + } else { + // Otherwise, just add the current character. + part += c; + } + } + + // Ensure the final part is included. If there's an open escape sequence + // it should be included. + if (escaped) { + part += "\\"; + } + result.push(part); + + return result; + } + + /** + * For a dotted field and event, fetch the value at that position, if one + * exists. + * + * @param key - The key of the push rule condition: a dotted field to fetch. + * @param ev - The matrix event to fetch the field from. + * @returns The value at the dotted path given by key. + */ private valueForDottedKey(key: string, ev: MatrixEvent): any { - const parts = key.split("."); + // The key should already have been parsed via updateCachedPushRuleKeys, + // but if it hasn't (maybe via an old consumer of the SDK which hasn't + // been updated?) then lazily calculate it here. + let parts = this.parsedKeys.get(key); + if (parts === undefined) { + parts = PushProcessor.partsForDottedKey(key); + this.parsedKeys.set(key, parts); + } let val: any; // special-case the first component to deal with encrypted messages const firstPart = parts[0]; + let currentIndex = 0; if (firstPart === "content") { val = ev.getContent(); - parts.shift(); + ++currentIndex; } else if (firstPart === "type") { val = ev.getType(); - parts.shift(); + ++currentIndex; } else { // use the raw event for any other fields val = ev.event; } - while (parts.length > 0) { - const thisPart = parts.shift()!; + for (; currentIndex < parts.length; ++currentIndex) { + const thisPart = parts[currentIndex]; if (isNullOrUndefined(val[thisPart])) { return null; } diff --git a/src/sliding-sync-sdk.ts b/src/sliding-sync-sdk.ts index f63a3046002..93e29e0baa3 100644 --- a/src/sliding-sync-sdk.ts +++ b/src/sliding-sync-sdk.ts @@ -43,7 +43,6 @@ import { } from "./sliding-sync"; import { EventType } from "./@types/event"; import { IPushRules } from "./@types/PushRules"; -import { PushProcessor } from "./pushprocessor"; import { RoomStateEvent } from "./models/room-state"; import { RoomMemberEvent } from "./models/room-member"; @@ -262,7 +261,7 @@ class ExtensionAccountData implements Extension(); - this.client.pushRules = PushProcessor.rewriteDefaultRules(rules); + this.client.setPushRules(rules); } const prevEvent = prevEventsMap[accountDataEvent.getType()]; this.client.emit(ClientEvent.AccountData, accountDataEvent, prevEvent); diff --git a/src/sync.ts b/src/sync.ts index bfd6029f0b3..057ee1540da 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -32,7 +32,6 @@ import * as utils from "./utils"; import { IDeferred } from "./utils"; import { Filter } from "./filter"; import { EventTimeline } from "./models/event-timeline"; -import { PushProcessor } from "./pushprocessor"; import { logger } from "./logger"; import { InvalidStoreError, InvalidStoreState } from "./errors"; import { ClientEvent, IStoredClientOpts, MatrixClient, PendingEventOrdering, ResetTimelineCallback } from "./client"; @@ -1162,7 +1161,7 @@ export class SyncApi { // (see sync) before syncing over the network. if (accountDataEvent.getType() === EventType.PushRules) { const rules = accountDataEvent.getContent(); - client.pushRules = PushProcessor.rewriteDefaultRules(rules); + client.setPushRules(rules); } const prevEvent = prevEventsMap[accountDataEvent.getType()!]; client.emit(ClientEvent.AccountData, accountDataEvent, prevEvent); From 933a0c9909d691ae0f9fafa03377dbcaa38a6024 Mon Sep 17 00:00:00 2001 From: Kerry Date: Thu, 2 Mar 2023 09:30:40 +1300 Subject: [PATCH 09/24] Polls push rules (#3181) * add poll push rule ids * add getPushRuleAndKindById method to pushprocessor --- spec/unit/pushprocessor.spec.ts | 57 ++++++++++++++++++++++++--------- src/@types/PushRules.ts | 8 +++++ src/pushprocessor.ts | 14 +++++++- 3 files changed, 62 insertions(+), 17 deletions(-) diff --git a/spec/unit/pushprocessor.spec.ts b/spec/unit/pushprocessor.spec.ts index f43d5f8aa6c..6fb02b18155 100644 --- a/spec/unit/pushprocessor.spec.ts +++ b/spec/unit/pushprocessor.spec.ts @@ -11,6 +11,23 @@ describe("NotificationService", function () { let pushProcessor: PushProcessor; + const msc3914RoomCallRule = { + rule_id: ".org.matrix.msc3914.rule.room.call", + default: true, + enabled: true, + conditions: [ + { + kind: "event_match", + key: "type", + pattern: "org.matrix.msc3401.call", + }, + { + kind: "call_started", + }, + ], + actions: ["notify", { set_tweak: "sound", value: "default" }], + }; + // These would be better if individual rules were configured in the tests themselves. const matrixClient = { getRoom: function () { @@ -163,22 +180,7 @@ describe("NotificationService", function () { enabled: true, rule_id: ".m.rule.room_one_to_one", }, - { - rule_id: ".org.matrix.msc3914.rule.room.call", - default: true, - enabled: true, - conditions: [ - { - kind: "event_match", - key: "type", - pattern: "org.matrix.msc3401.call", - }, - { - kind: "call_started", - }, - ], - actions: ["notify", { set_tweak: "sound", value: "default" }], - }, + msc3914RoomCallRule, ], room: [], sender: [], @@ -549,6 +551,29 @@ describe("NotificationService", function () { ), ).toBe(expected); }); + + describe("getPushRuleById()", () => { + it("returns null when rule id is not in rule set", () => { + expect(pushProcessor.getPushRuleById("non-existant-rule")).toBeNull(); + }); + + it("returns push rule when it is found in rule set", () => { + expect(pushProcessor.getPushRuleById(".org.matrix.msc3914.rule.room.call")).toEqual(msc3914RoomCallRule); + }); + }); + + describe("getPushRuleAndKindById()", () => { + it("returns null when rule id is not in rule set", () => { + expect(pushProcessor.getPushRuleAndKindById("non-existant-rule")).toBeNull(); + }); + + it("returns push rule when it is found in rule set", () => { + expect(pushProcessor.getPushRuleAndKindById(".org.matrix.msc3914.rule.room.call")).toEqual({ + kind: "override", + rule: msc3914RoomCallRule, + }); + }); + }); }); describe("Test PushProcessor.partsForDottedKey", function () { diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts index 56a93df9fb3..ab581f3680c 100644 --- a/src/@types/PushRules.ts +++ b/src/@types/PushRules.ts @@ -133,6 +133,14 @@ export enum RuleId { IncomingCall = ".m.rule.call", SuppressNotices = ".m.rule.suppress_notices", Tombstone = ".m.rule.tombstone", + PollStart = ".m.rule.poll_start", + PollStartUnstable = ".org.matrix.msc3930.rule.poll_start", + PollEnd = ".m.rule.poll_end", + PollEndUnstable = ".org.matrix.msc3930.rule.poll_end", + PollStartOneToOne = ".m.rule.poll_start_one_to_one", + PollStartOneToOneUnstable = ".org.matrix.msc3930.rule.poll_start_one_to_one", + PollEndOneToOne = ".m.rule.poll_end_one_to_one", + PollEndOneToOneUnstable = ".org.matrix.msc3930.rule.poll_end_one_to_one", } export type PushRuleSet = { diff --git a/src/pushprocessor.ts b/src/pushprocessor.ts index 2bbf8fbdb9c..76f18d90081 100644 --- a/src/pushprocessor.ts +++ b/src/pushprocessor.ts @@ -634,6 +634,18 @@ export class PushProcessor { * @returns The push rule, or null if no such rule was found */ public getPushRuleById(ruleId: string): IPushRule | null { + const result = this.getPushRuleAndKindById(ruleId); + return result?.rule ?? null; + } + + /** + * Get one of the users push rules by its ID + * + * @param ruleId - The ID of the rule to search for + * @returns rule The push rule, or null if no such rule was found + * @returns kind - The PushRuleKind of the rule to search for + */ + public getPushRuleAndKindById(ruleId: string): { rule: IPushRule; kind: PushRuleKind } | null { for (const scope of ["global"] as const) { if (this.client.pushRules?.[scope] === undefined) continue; @@ -641,7 +653,7 @@ export class PushProcessor { if (this.client.pushRules[scope][kind] === undefined) continue; for (const rule of this.client.pushRules[scope][kind]!) { - if (rule.rule_id === ruleId) return rule; + if (rule.rule_id === ruleId) return { rule, kind }; } } } From 86256a4e74751d98e67f18d8af0a80c5de3006e4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Mar 2023 07:23:42 +0000 Subject: [PATCH 10/24] Update definitelyTyped (#3170) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- yarn.lock | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/yarn.lock b/yarn.lock index 9f99a9e137f..1770925086b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1828,9 +1828,9 @@ integrity sha512-5EWrvLmglK+imbCJY0+INViFWUHg1AHel1sq4ZVSfdcNqGy9Edv3UB9IIzzg+xPaUcAgZYcfVs2fBcwDeZzU0A== "@types/node@18": - version "18.13.0" - resolved "https://registry.yarnpkg.com/@types/node/-/node-18.13.0.tgz#0400d1e6ce87e9d3032c19eb6c58205b0d3f7850" - integrity sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg== + version "18.14.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.14.2.tgz#c076ed1d7b6095078ad3cf21dfeea951842778b1" + integrity sha512-1uEQxww3DaghA0RxqHx0O0ppVlo43pJhepY51OxuQIKHpjbnYLA7vcdwioNPzIqmC2u3I/dmylcqjlh0e7AyUA== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -1868,9 +1868,9 @@ integrity sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw== "@types/uuid@9": - version "9.0.0" - resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.0.tgz#53ef263e5239728b56096b0a869595135b7952d2" - integrity sha512-kr90f+ERiQtKWMz5rP32ltJ/BtULDI5RVO0uavn1HQUOwjx0R1h0rnDYNL0CepF1zL5bSY6FISAfd9tOdDhU5Q== + version "9.0.1" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.1.tgz#98586dc36aee8dacc98cc396dbca8d0429647aa6" + integrity sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA== "@types/webidl-conversions@*": version "7.0.0" From 41782c4593b4f09c7261eb9d73f5930717cf9559 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 2 Mar 2023 07:23:55 +0000 Subject: [PATCH 11/24] Update dependency eslint-plugin-jsdoc to v40 (#3173) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 33abb311bae..7e4c2f7d90f 100644 --- a/package.json +++ b/package.json @@ -106,7 +106,7 @@ "eslint-import-resolver-typescript": "^3.5.1", "eslint-plugin-import": "^2.26.0", "eslint-plugin-jest": "^27.1.6", - "eslint-plugin-jsdoc": "^39.6.4", + "eslint-plugin-jsdoc": "^40.0.0", "eslint-plugin-matrix-org": "^1.0.0", "eslint-plugin-tsdoc": "^0.2.17", "eslint-plugin-unicorn": "^45.0.0", diff --git a/yarn.lock b/yarn.lock index 1770925086b..1e138046ae5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3551,10 +3551,10 @@ eslint-plugin-jest@^27.1.6: dependencies: "@typescript-eslint/utils" "^5.10.0" -eslint-plugin-jsdoc@^39.6.4: - version "39.9.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.9.1.tgz#e9ce1723411fd7ea0933b3ef0dd02156ae3068e2" - integrity sha512-Rq2QY6BZP2meNIs48aZ3GlIlJgBqFCmR55+UBvaDkA3ZNQ0SvQXOs2QKkubakEijV8UbIVbVZKsOVN8G3MuqZw== +eslint-plugin-jsdoc@^40.0.0: + version "40.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-40.0.0.tgz#7f433757aa91721e4b88a527dc17ac0437c3c075" + integrity sha512-LOPyIu1vAVvGPkye3ci0moj0iNf3f8bmin6do2DYDj+77NRXWnkmhKRy8swWsatUs3mB5jYPWPUsFg9pyfEiyA== dependencies: "@es-joy/jsdoccomment" "~0.36.1" comment-parser "1.3.1" From 493203050a3809bbe36b927cced578d44e1a8a17 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Thu, 2 Mar 2023 13:15:17 +0000 Subject: [PATCH 12/24] Support for v2 of MSC3903 (#3155) * v2 of MSC3903 implementation This is a deliberate breaking change on an unstable feature. * Test correct protocol version * Fix up test * v2 of MSC3903 implementation This is a deliberate breaking change on an unstable feature. * Test correct protocol version * Fix up test * Reinstate v1 support to make this a non-breaking change Deprecates several experimental types --- .../{ecdh.spec.ts => ecdhv1.spec.ts} | 0 spec/unit/rendezvous/ecdhv2.spec.ts | 172 ++++++++++++ spec/unit/rendezvous/rendezvous.spec.ts | 44 +-- .../MSC3903ECDHv1RendezvousChannel.ts | 23 +- .../MSC3903ECDHv2RendezvousChannel.ts | 260 ++++++++++++++++++ src/rendezvous/channels/index.ts | 1 + 6 files changed, 465 insertions(+), 35 deletions(-) rename spec/unit/rendezvous/{ecdh.spec.ts => ecdhv1.spec.ts} (100%) create mode 100644 spec/unit/rendezvous/ecdhv2.spec.ts create mode 100644 src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts diff --git a/spec/unit/rendezvous/ecdh.spec.ts b/spec/unit/rendezvous/ecdhv1.spec.ts similarity index 100% rename from spec/unit/rendezvous/ecdh.spec.ts rename to spec/unit/rendezvous/ecdhv1.spec.ts diff --git a/spec/unit/rendezvous/ecdhv2.spec.ts b/spec/unit/rendezvous/ecdhv2.spec.ts new file mode 100644 index 00000000000..92559bf050e --- /dev/null +++ b/spec/unit/rendezvous/ecdhv2.spec.ts @@ -0,0 +1,172 @@ +/* +Copyright 2022 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import "../../olm-loader"; +import { RendezvousFailureReason, RendezvousIntent } from "../../../src/rendezvous"; +import { MSC3903ECDHPayload, MSC3903ECDHv2RendezvousChannel } from "../../../src/rendezvous/channels"; +import { decodeBase64 } from "../../../src/crypto/olmlib"; +import { DummyTransport } from "./DummyTransport"; + +function makeTransport(name: string) { + return new DummyTransport(name, { type: "dummy" }); +} + +describe("ECDHv2", function () { + beforeAll(async function () { + await global.Olm.init(); + }); + + describe("with crypto", () => { + it("initiator wants to sign in", async function () { + const aliceTransport = makeTransport("Alice"); + const bobTransport = makeTransport("Bob"); + aliceTransport.otherParty = bobTransport; + bobTransport.otherParty = aliceTransport; + + // alice is signing in initiates and generates a code + const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport); + const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); + const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); + + const bobChecksum = await bob.connect(); + const aliceChecksum = await alice.connect(); + + expect(aliceChecksum).toEqual(bobChecksum); + + const message = { key: "xxx" }; + await alice.send(message); + const bobReceive = await bob.receive(); + expect(bobReceive).toEqual(message); + + await alice.cancel(RendezvousFailureReason.Unknown); + await bob.cancel(RendezvousFailureReason.Unknown); + }); + + it("initiator wants to reciprocate", async function () { + const aliceTransport = makeTransport("Alice"); + const bobTransport = makeTransport("Bob"); + aliceTransport.otherParty = bobTransport; + bobTransport.otherParty = aliceTransport; + + // alice is signing in initiates and generates a code + const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport); + const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); + const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); + + const bobChecksum = await bob.connect(); + const aliceChecksum = await alice.connect(); + + expect(aliceChecksum).toEqual(bobChecksum); + + const message = { key: "xxx" }; + await bob.send(message); + const aliceReceive = await alice.receive(); + expect(aliceReceive).toEqual(message); + + await alice.cancel(RendezvousFailureReason.Unknown); + await bob.cancel(RendezvousFailureReason.Unknown); + }); + + it("double connect", async function () { + const aliceTransport = makeTransport("Alice"); + const bobTransport = makeTransport("Bob"); + aliceTransport.otherParty = bobTransport; + bobTransport.otherParty = aliceTransport; + + // alice is signing in initiates and generates a code + const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport); + const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); + const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); + + const bobChecksum = await bob.connect(); + const aliceChecksum = await alice.connect(); + + expect(aliceChecksum).toEqual(bobChecksum); + + expect(alice.connect()).rejects.toThrow(); + + await alice.cancel(RendezvousFailureReason.Unknown); + await bob.cancel(RendezvousFailureReason.Unknown); + }); + + it("closed", async function () { + const aliceTransport = makeTransport("Alice"); + const bobTransport = makeTransport("Bob"); + aliceTransport.otherParty = bobTransport; + bobTransport.otherParty = aliceTransport; + + // alice is signing in initiates and generates a code + const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport); + const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); + const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); + + const bobChecksum = await bob.connect(); + const aliceChecksum = await alice.connect(); + + expect(aliceChecksum).toEqual(bobChecksum); + + alice.close(); + + expect(alice.connect()).rejects.toThrow(); + expect(alice.send({})).rejects.toThrow(); + expect(alice.receive()).rejects.toThrow(); + + await alice.cancel(RendezvousFailureReason.Unknown); + await bob.cancel(RendezvousFailureReason.Unknown); + }); + + it("require ciphertext", async function () { + const aliceTransport = makeTransport("Alice"); + const bobTransport = makeTransport("Bob"); + aliceTransport.otherParty = bobTransport; + bobTransport.otherParty = aliceTransport; + + // alice is signing in initiates and generates a code + const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport); + const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); + const bob = new MSC3903ECDHv2RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); + + const bobChecksum = await bob.connect(); + const aliceChecksum = await alice.connect(); + + expect(aliceChecksum).toEqual(bobChecksum); + + // send a message without encryption + await aliceTransport.send({ iv: "dummy", ciphertext: "dummy" }); + expect(bob.receive()).rejects.toThrow(); + + await alice.cancel(RendezvousFailureReason.Unknown); + await bob.cancel(RendezvousFailureReason.Unknown); + }); + + it("ciphertext before set up", async function () { + const aliceTransport = makeTransport("Alice"); + const bobTransport = makeTransport("Bob"); + aliceTransport.otherParty = bobTransport; + bobTransport.otherParty = aliceTransport; + + // alice is signing in initiates and generates a code + const alice = new MSC3903ECDHv2RendezvousChannel(aliceTransport); + await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); + + await bobTransport.send({ iv: "dummy", ciphertext: "dummy" }); + + expect(alice.receive()).rejects.toThrow(); + + await alice.cancel(RendezvousFailureReason.Unknown); + }); + }); +}); diff --git a/spec/unit/rendezvous/rendezvous.spec.ts b/spec/unit/rendezvous/rendezvous.spec.ts index 07187647630..59a3ac71613 100644 --- a/spec/unit/rendezvous/rendezvous.spec.ts +++ b/spec/unit/rendezvous/rendezvous.spec.ts @@ -19,9 +19,9 @@ import MockHttpBackend from "matrix-mock-request"; import "../../olm-loader"; import { MSC3906Rendezvous, RendezvousCode, RendezvousFailureReason, RendezvousIntent } from "../../../src/rendezvous"; import { - ECDHv1RendezvousCode, + ECDHv2RendezvousCode as ECDHRendezvousCode, MSC3903ECDHPayload, - MSC3903ECDHv1RendezvousChannel, + MSC3903ECDHv2RendezvousChannel as MSC3903ECDHRendezvousChannel, } from "../../../src/rendezvous/channels"; import { MatrixClient } from "../../../src"; import { @@ -126,7 +126,7 @@ describe("Rendezvous", function () { fallbackRzServer: "https://fallbackserver/rz", fetchFn, }); - const aliceEcdh = new MSC3903ECDHv1RendezvousChannel(aliceTransport); + const aliceEcdh = new MSC3903ECDHRendezvousChannel(aliceTransport); const aliceRz = new MSC3906Rendezvous(aliceEcdh, alice); expect(aliceRz.code).toBeUndefined(); @@ -143,7 +143,7 @@ describe("Rendezvous", function () { const code = JSON.parse(aliceRz.code!) as RendezvousCode; expect(code.intent).toEqual(RendezvousIntent.RECIPROCATE_LOGIN_ON_EXISTING_DEVICE); - expect(code.rendezvous?.algorithm).toEqual("org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256"); + expect(code.rendezvous?.algorithm).toEqual("org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256"); expect(code.rendezvous?.transport.type).toEqual("org.matrix.msc3886.http.v1"); expect((code.rendezvous?.transport as MSC3886SimpleHttpRendezvousTransportDetails).uri).toEqual( "https://fallbackserver/rz/123", @@ -181,11 +181,11 @@ describe("Rendezvous", function () { msc3882Enabled: false, msc3886Enabled: false, }); - const aliceEcdh = new MSC3903ECDHv1RendezvousChannel(aliceTransport, undefined, aliceOnFailure); + const aliceEcdh = new MSC3903ECDHRendezvousChannel(aliceTransport, undefined, aliceOnFailure); const aliceRz = new MSC3906Rendezvous(aliceEcdh, alice); aliceTransport.onCancelled = aliceOnFailure; await aliceRz.generateCode(); - const code = JSON.parse(aliceRz.code!) as ECDHv1RendezvousCode; + const code = JSON.parse(aliceRz.code!) as ECDHRendezvousCode; expect(code.rendezvous.key).toBeDefined(); @@ -193,7 +193,7 @@ describe("Rendezvous", function () { // bob is try to sign in and scans the code const bobOnFailure = jest.fn(); - const bobEcdh = new MSC3903ECDHv1RendezvousChannel( + const bobEcdh = new MSC3903ECDHRendezvousChannel( bobTransport, decodeBase64(code.rendezvous.key), // alice's public key bobOnFailure, @@ -235,11 +235,11 @@ describe("Rendezvous", function () { msc3882Enabled: true, msc3886Enabled: false, }); - const aliceEcdh = new MSC3903ECDHv1RendezvousChannel(aliceTransport, undefined, aliceOnFailure); + const aliceEcdh = new MSC3903ECDHRendezvousChannel(aliceTransport, undefined, aliceOnFailure); const aliceRz = new MSC3906Rendezvous(aliceEcdh, alice); aliceTransport.onCancelled = aliceOnFailure; await aliceRz.generateCode(); - const code = JSON.parse(aliceRz.code!) as ECDHv1RendezvousCode; + const code = JSON.parse(aliceRz.code!) as ECDHRendezvousCode; expect(code.rendezvous.key).toBeDefined(); @@ -247,7 +247,7 @@ describe("Rendezvous", function () { // bob is try to sign in and scans the code const bobOnFailure = jest.fn(); - const bobEcdh = new MSC3903ECDHv1RendezvousChannel( + const bobEcdh = new MSC3903ECDHRendezvousChannel( bobTransport, decodeBase64(code.rendezvous.key), // alice's public key bobOnFailure, @@ -293,11 +293,11 @@ describe("Rendezvous", function () { msc3882Enabled: true, msc3886Enabled: false, }); - const aliceEcdh = new MSC3903ECDHv1RendezvousChannel(aliceTransport, undefined, aliceOnFailure); + const aliceEcdh = new MSC3903ECDHRendezvousChannel(aliceTransport, undefined, aliceOnFailure); const aliceRz = new MSC3906Rendezvous(aliceEcdh, alice); aliceTransport.onCancelled = aliceOnFailure; await aliceRz.generateCode(); - const code = JSON.parse(aliceRz.code!) as ECDHv1RendezvousCode; + const code = JSON.parse(aliceRz.code!) as ECDHRendezvousCode; expect(code.rendezvous.key).toBeDefined(); @@ -305,7 +305,7 @@ describe("Rendezvous", function () { // bob is try to sign in and scans the code const bobOnFailure = jest.fn(); - const bobEcdh = new MSC3903ECDHv1RendezvousChannel( + const bobEcdh = new MSC3903ECDHRendezvousChannel( bobTransport, decodeBase64(code.rendezvous.key), // alice's public key bobOnFailure, @@ -351,11 +351,11 @@ describe("Rendezvous", function () { msc3882Enabled: true, msc3886Enabled: false, }); - const aliceEcdh = new MSC3903ECDHv1RendezvousChannel(aliceTransport, undefined, aliceOnFailure); + const aliceEcdh = new MSC3903ECDHRendezvousChannel(aliceTransport, undefined, aliceOnFailure); const aliceRz = new MSC3906Rendezvous(aliceEcdh, alice); aliceTransport.onCancelled = aliceOnFailure; await aliceRz.generateCode(); - const code = JSON.parse(aliceRz.code!) as ECDHv1RendezvousCode; + const code = JSON.parse(aliceRz.code!) as ECDHRendezvousCode; expect(code.rendezvous.key).toBeDefined(); @@ -363,7 +363,7 @@ describe("Rendezvous", function () { // bob is try to sign in and scans the code const bobOnFailure = jest.fn(); - const bobEcdh = new MSC3903ECDHv1RendezvousChannel( + const bobEcdh = new MSC3903ECDHRendezvousChannel( bobTransport, decodeBase64(code.rendezvous.key), // alice's public key bobOnFailure, @@ -411,11 +411,11 @@ describe("Rendezvous", function () { msc3882Enabled: true, msc3886Enabled: false, }); - const aliceEcdh = new MSC3903ECDHv1RendezvousChannel(aliceTransport, undefined, aliceOnFailure); + const aliceEcdh = new MSC3903ECDHRendezvousChannel(aliceTransport, undefined, aliceOnFailure); const aliceRz = new MSC3906Rendezvous(aliceEcdh, alice); aliceTransport.onCancelled = aliceOnFailure; await aliceRz.generateCode(); - const code = JSON.parse(aliceRz.code!) as ECDHv1RendezvousCode; + const code = JSON.parse(aliceRz.code!) as ECDHRendezvousCode; expect(code.rendezvous.key).toBeDefined(); @@ -423,7 +423,7 @@ describe("Rendezvous", function () { // bob is try to sign in and scans the code const bobOnFailure = jest.fn(); - const bobEcdh = new MSC3903ECDHv1RendezvousChannel( + const bobEcdh = new MSC3903ECDHRendezvousChannel( bobTransport, decodeBase64(code.rendezvous.key), // alice's public key bobOnFailure, @@ -485,11 +485,11 @@ describe("Rendezvous", function () { master: "mmmmm", }, }); - const aliceEcdh = new MSC3903ECDHv1RendezvousChannel(aliceTransport, undefined, aliceOnFailure); + const aliceEcdh = new MSC3903ECDHRendezvousChannel(aliceTransport, undefined, aliceOnFailure); const aliceRz = new MSC3906Rendezvous(aliceEcdh, alice); aliceTransport.onCancelled = aliceOnFailure; await aliceRz.generateCode(); - const code = JSON.parse(aliceRz.code!) as ECDHv1RendezvousCode; + const code = JSON.parse(aliceRz.code!) as ECDHRendezvousCode; expect(code.rendezvous.key).toBeDefined(); @@ -497,7 +497,7 @@ describe("Rendezvous", function () { // bob is try to sign in and scans the code const bobOnFailure = jest.fn(); - const bobEcdh = new MSC3903ECDHv1RendezvousChannel( + const bobEcdh = new MSC3903ECDHRendezvousChannel( bobTransport, decodeBase64(code.rendezvous.key), // alice's public key bobOnFailure, diff --git a/src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts b/src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts index 24ebcbe4c2e..573ae6f2297 100644 --- a/src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts +++ b/src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts @@ -29,12 +29,19 @@ import { encodeBase64, decodeBase64 } from "../../crypto/olmlib"; import { crypto, subtleCrypto, TextEncoder } from "../../crypto/crypto"; import { generateDecimalSas } from "../../crypto/verification/SASDecimal"; import { UnstableValue } from "../../NamespacedValue"; +import { EncryptedPayload, MSC3903ECDHPayload, PlainTextPayload } from "./MSC3903ECDHv2RendezvousChannel"; -const ECDH_V1 = new UnstableValue( +/** + * @deprecated Use ECDH_V2 instead + */ +export const ECDH_V1 = new UnstableValue( "m.rendezvous.v1.curve25519-aes-sha256", "org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256", ); +/** + * @deprecated Use ECDHv2RendezvousCode instead + */ export interface ECDHv1RendezvousCode extends RendezvousCode { rendezvous: { transport: RendezvousTransportDetails; @@ -43,18 +50,6 @@ export interface ECDHv1RendezvousCode extends RendezvousCode { }; } -export type MSC3903ECDHPayload = PlainTextPayload | EncryptedPayload; - -export interface PlainTextPayload { - algorithm: typeof ECDH_V1.name | typeof ECDH_V1.altName; - key?: string; -} - -export interface EncryptedPayload { - iv: string; - ciphertext: string; -} - async function importKey(key: Uint8Array): Promise { if (!subtleCrypto) { throw new Error("Web Crypto is not available"); @@ -69,6 +64,8 @@ async function importKey(key: Uint8Array): Promise { * Implementation of the unstable [MSC3903](https://github.com/matrix-org/matrix-spec-proposals/pull/3903) * X25519/ECDH key agreement based secure rendezvous channel. * Note that this is UNSTABLE and may have breaking changes without notice. + * + * @deprecated Use MSC3903ECDHv2RendezvousChannel instead. This implementation will be removed. */ export class MSC3903ECDHv1RendezvousChannel implements RendezvousChannel { private olmSAS?: SAS; diff --git a/src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts b/src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts new file mode 100644 index 00000000000..312aaa5c2e3 --- /dev/null +++ b/src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts @@ -0,0 +1,260 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +import { SAS } from "@matrix-org/olm"; + +import { + RendezvousError, + RendezvousCode, + RendezvousIntent, + RendezvousChannel, + RendezvousTransportDetails, + RendezvousTransport, + RendezvousFailureReason, +} from ".."; +import { encodeUnpaddedBase64, decodeBase64 } from "../../crypto/olmlib"; +import { crypto, subtleCrypto, TextEncoder } from "../../crypto/crypto"; +import { generateDecimalSas } from "../../crypto/verification/SASDecimal"; +import { UnstableValue } from "../../NamespacedValue"; +import { ECDH_V1 } from "./MSC3903ECDHv1RendezvousChannel"; + +const ECDH_V2 = new UnstableValue( + "m.rendezvous.v2.curve25519-aes-sha256", + "org.matrix.msc3903.rendezvous.v2.curve25519-aes-sha256", +); + +export interface ECDHv2RendezvousCode extends RendezvousCode { + rendezvous: { + transport: RendezvousTransportDetails; + algorithm: typeof ECDH_V2.name | typeof ECDH_V2.altName | typeof ECDH_V1.name | typeof ECDH_V1.altName; + key: string; + }; +} + +export type MSC3903ECDHPayload = PlainTextPayload | EncryptedPayload; + +export interface PlainTextPayload { + algorithm: typeof ECDH_V2.name | typeof ECDH_V2.altName | typeof ECDH_V1.name | typeof ECDH_V1.altName; + key?: string; +} + +export interface EncryptedPayload { + iv: string; + ciphertext: string; +} + +async function importKey(key: Uint8Array): Promise { + if (!subtleCrypto) { + throw new Error("Web Crypto is not available"); + } + + const imported = subtleCrypto.importKey("raw", key, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]); + + return imported; +} + +/** + * Implementation of the unstable [MSC3903](https://github.com/matrix-org/matrix-spec-proposals/pull/3903) + * X25519/ECDH key agreement based secure rendezvous channel. + * Note that this is UNSTABLE and may have breaking changes without notice. + */ +export class MSC3903ECDHv2RendezvousChannel implements RendezvousChannel { + private olmSAS?: SAS; + private ourPublicKey: Uint8Array; + private aesKey?: CryptoKey; + private connected = false; + + public constructor( + private transport: RendezvousTransport, + private theirPublicKey?: Uint8Array, + public onFailure?: (reason: RendezvousFailureReason) => void, + ) { + this.olmSAS = new global.Olm.SAS(); + this.ourPublicKey = decodeBase64(this.olmSAS.get_pubkey()); + } + + public async generateCode(intent: RendezvousIntent): Promise { + if (this.transport.ready) { + throw new Error("Code already generated"); + } + + await this.transport.send({ algorithm: ECDH_V2.name }); + + const rendezvous: ECDHv2RendezvousCode = { + rendezvous: { + algorithm: ECDH_V2.name, + key: encodeUnpaddedBase64(this.ourPublicKey), + transport: await this.transport.details(), + }, + intent, + }; + + return rendezvous; + } + + public async connect(): Promise { + if (this.connected) { + throw new Error("Channel already connected"); + } + + if (!this.olmSAS) { + throw new Error("Channel closed"); + } + + const isInitiator = !this.theirPublicKey; + + if (isInitiator) { + // wait for the other side to send us their public key + const rawRes = await this.transport.receive(); + if (!rawRes) { + throw new Error("No response from other device"); + } + const res = rawRes as Partial; + const { key, algorithm } = res; + if (!algorithm || !ECDH_V2.matches(algorithm) || !key) { + throw new RendezvousError( + "Unsupported algorithm: " + algorithm, + RendezvousFailureReason.UnsupportedAlgorithm, + ); + } + + this.theirPublicKey = decodeBase64(key); + } else { + // send our public key unencrypted + await this.transport.send({ + algorithm: ECDH_V2.name, + key: encodeUnpaddedBase64(this.ourPublicKey), + }); + } + + this.connected = true; + + this.olmSAS.set_their_key(encodeUnpaddedBase64(this.theirPublicKey!)); + + const initiatorKey = isInitiator ? this.ourPublicKey : this.theirPublicKey!; + const recipientKey = isInitiator ? this.theirPublicKey! : this.ourPublicKey; + let aesInfo = ECDH_V2.name; + aesInfo += `|${encodeUnpaddedBase64(initiatorKey)}`; + aesInfo += `|${encodeUnpaddedBase64(recipientKey)}`; + + const aesKeyBytes = this.olmSAS.generate_bytes(aesInfo, 32); + + this.aesKey = await importKey(aesKeyBytes); + + // blank the bytes out to make sure not kept in memory + aesKeyBytes.fill(0); + + const rawChecksum = this.olmSAS.generate_bytes(aesInfo, 5); + return generateDecimalSas(Array.from(rawChecksum)).join("-"); + } + + private async encrypt(data: T): Promise { + if (!subtleCrypto) { + throw new Error("Web Crypto is not available"); + } + + const iv = new Uint8Array(32); + crypto.getRandomValues(iv); + + const encodedData = new TextEncoder().encode(JSON.stringify(data)); + + const ciphertext = await subtleCrypto.encrypt( + { + name: "AES-GCM", + iv, + tagLength: 128, + }, + this.aesKey as CryptoKey, + encodedData, + ); + + return { + iv: encodeUnpaddedBase64(iv), + ciphertext: encodeUnpaddedBase64(ciphertext), + }; + } + + public async send(payload: T): Promise { + if (!this.olmSAS) { + throw new Error("Channel closed"); + } + + if (!this.aesKey) { + throw new Error("Shared secret not set up"); + } + + return this.transport.send(await this.encrypt(payload)); + } + + private async decrypt({ iv, ciphertext }: EncryptedPayload): Promise> { + if (!ciphertext || !iv) { + throw new Error("Missing ciphertext and/or iv"); + } + + const ciphertextBytes = decodeBase64(ciphertext); + + if (!subtleCrypto) { + throw new Error("Web Crypto is not available"); + } + + const plaintext = await subtleCrypto.decrypt( + { + name: "AES-GCM", + iv: decodeBase64(iv), + tagLength: 128, + }, + this.aesKey as CryptoKey, + ciphertextBytes, + ); + + return JSON.parse(new TextDecoder().decode(new Uint8Array(plaintext))); + } + + public async receive(): Promise | undefined> { + if (!this.olmSAS) { + throw new Error("Channel closed"); + } + if (!this.aesKey) { + throw new Error("Shared secret not set up"); + } + + const rawData = await this.transport.receive(); + if (!rawData) { + return undefined; + } + const data = rawData as Partial; + if (data.ciphertext && data.iv) { + return this.decrypt(data as EncryptedPayload); + } + + throw new Error("Data received but no ciphertext"); + } + + public async close(): Promise { + if (this.olmSAS) { + this.olmSAS.free(); + this.olmSAS = undefined; + } + } + + public async cancel(reason: RendezvousFailureReason): Promise { + try { + await this.transport.cancel(reason); + } finally { + await this.close(); + } + } +} diff --git a/src/rendezvous/channels/index.ts b/src/rendezvous/channels/index.ts index 072a1014694..42e0ee15e9e 100644 --- a/src/rendezvous/channels/index.ts +++ b/src/rendezvous/channels/index.ts @@ -15,3 +15,4 @@ limitations under the License. */ export * from "./MSC3903ECDHv1RendezvousChannel"; +export * from "./MSC3903ECDHv2RendezvousChannel"; From 565339b1fd37f602ae2b80de0ae37b2d6666480b Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Thu, 2 Mar 2023 16:34:22 +0000 Subject: [PATCH 13/24] Remove experimental support for MSC3903 v1 (#3184) * v2 of MSC3903 implementation This is a deliberate breaking change on an unstable feature. * Reinstate v1 support to make this a non-breaking change Deprecates several experimental types * Remove MSC3903 v1 support This is a breaking change in code marked unstable/experimental Revert "Reinstate v1 support to make this a non-breaking change" This reverts commit 89773458b9a1e5f332938e5574f35b16d204d75d. --- spec/unit/rendezvous/ecdhv1.spec.ts | 172 ------------ .../MSC3903ECDHv1RendezvousChannel.ts | 256 ------------------ .../MSC3903ECDHv2RendezvousChannel.ts | 5 +- src/rendezvous/channels/index.ts | 1 - 4 files changed, 2 insertions(+), 432 deletions(-) delete mode 100644 spec/unit/rendezvous/ecdhv1.spec.ts delete mode 100644 src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts diff --git a/spec/unit/rendezvous/ecdhv1.spec.ts b/spec/unit/rendezvous/ecdhv1.spec.ts deleted file mode 100644 index f088977f056..00000000000 --- a/spec/unit/rendezvous/ecdhv1.spec.ts +++ /dev/null @@ -1,172 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import "../../olm-loader"; -import { RendezvousFailureReason, RendezvousIntent } from "../../../src/rendezvous"; -import { MSC3903ECDHPayload, MSC3903ECDHv1RendezvousChannel } from "../../../src/rendezvous/channels"; -import { decodeBase64 } from "../../../src/crypto/olmlib"; -import { DummyTransport } from "./DummyTransport"; - -function makeTransport(name: string) { - return new DummyTransport(name, { type: "dummy" }); -} - -describe("ECDHv1", function () { - beforeAll(async function () { - await global.Olm.init(); - }); - - describe("with crypto", () => { - it("initiator wants to sign in", async function () { - const aliceTransport = makeTransport("Alice"); - const bobTransport = makeTransport("Bob"); - aliceTransport.otherParty = bobTransport; - bobTransport.otherParty = aliceTransport; - - // alice is signing in initiates and generates a code - const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport); - const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); - const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); - - const bobChecksum = await bob.connect(); - const aliceChecksum = await alice.connect(); - - expect(aliceChecksum).toEqual(bobChecksum); - - const message = { key: "xxx" }; - await alice.send(message); - const bobReceive = await bob.receive(); - expect(bobReceive).toEqual(message); - - await alice.cancel(RendezvousFailureReason.Unknown); - await bob.cancel(RendezvousFailureReason.Unknown); - }); - - it("initiator wants to reciprocate", async function () { - const aliceTransport = makeTransport("Alice"); - const bobTransport = makeTransport("Bob"); - aliceTransport.otherParty = bobTransport; - bobTransport.otherParty = aliceTransport; - - // alice is signing in initiates and generates a code - const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport); - const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); - const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); - - const bobChecksum = await bob.connect(); - const aliceChecksum = await alice.connect(); - - expect(aliceChecksum).toEqual(bobChecksum); - - const message = { key: "xxx" }; - await bob.send(message); - const aliceReceive = await alice.receive(); - expect(aliceReceive).toEqual(message); - - await alice.cancel(RendezvousFailureReason.Unknown); - await bob.cancel(RendezvousFailureReason.Unknown); - }); - - it("double connect", async function () { - const aliceTransport = makeTransport("Alice"); - const bobTransport = makeTransport("Bob"); - aliceTransport.otherParty = bobTransport; - bobTransport.otherParty = aliceTransport; - - // alice is signing in initiates and generates a code - const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport); - const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); - const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); - - const bobChecksum = await bob.connect(); - const aliceChecksum = await alice.connect(); - - expect(aliceChecksum).toEqual(bobChecksum); - - expect(alice.connect()).rejects.toThrow(); - - await alice.cancel(RendezvousFailureReason.Unknown); - await bob.cancel(RendezvousFailureReason.Unknown); - }); - - it("closed", async function () { - const aliceTransport = makeTransport("Alice"); - const bobTransport = makeTransport("Bob"); - aliceTransport.otherParty = bobTransport; - bobTransport.otherParty = aliceTransport; - - // alice is signing in initiates and generates a code - const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport); - const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); - const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); - - const bobChecksum = await bob.connect(); - const aliceChecksum = await alice.connect(); - - expect(aliceChecksum).toEqual(bobChecksum); - - alice.close(); - - expect(alice.connect()).rejects.toThrow(); - expect(alice.send({})).rejects.toThrow(); - expect(alice.receive()).rejects.toThrow(); - - await alice.cancel(RendezvousFailureReason.Unknown); - await bob.cancel(RendezvousFailureReason.Unknown); - }); - - it("require ciphertext", async function () { - const aliceTransport = makeTransport("Alice"); - const bobTransport = makeTransport("Bob"); - aliceTransport.otherParty = bobTransport; - bobTransport.otherParty = aliceTransport; - - // alice is signing in initiates and generates a code - const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport); - const aliceCode = await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); - const bob = new MSC3903ECDHv1RendezvousChannel(bobTransport, decodeBase64(aliceCode.rendezvous.key)); - - const bobChecksum = await bob.connect(); - const aliceChecksum = await alice.connect(); - - expect(aliceChecksum).toEqual(bobChecksum); - - // send a message without encryption - await aliceTransport.send({ iv: "dummy", ciphertext: "dummy" }); - expect(bob.receive()).rejects.toThrow(); - - await alice.cancel(RendezvousFailureReason.Unknown); - await bob.cancel(RendezvousFailureReason.Unknown); - }); - - it("ciphertext before set up", async function () { - const aliceTransport = makeTransport("Alice"); - const bobTransport = makeTransport("Bob"); - aliceTransport.otherParty = bobTransport; - bobTransport.otherParty = aliceTransport; - - // alice is signing in initiates and generates a code - const alice = new MSC3903ECDHv1RendezvousChannel(aliceTransport); - await alice.generateCode(RendezvousIntent.LOGIN_ON_NEW_DEVICE); - - await bobTransport.send({ iv: "dummy", ciphertext: "dummy" }); - - expect(alice.receive()).rejects.toThrow(); - - await alice.cancel(RendezvousFailureReason.Unknown); - }); - }); -}); diff --git a/src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts b/src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts deleted file mode 100644 index 573ae6f2297..00000000000 --- a/src/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.ts +++ /dev/null @@ -1,256 +0,0 @@ -/* -Copyright 2022 The Matrix.org Foundation C.I.C. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -*/ - -import { SAS } from "@matrix-org/olm"; - -import { - RendezvousError, - RendezvousCode, - RendezvousIntent, - RendezvousChannel, - RendezvousTransportDetails, - RendezvousTransport, - RendezvousFailureReason, -} from ".."; -import { encodeBase64, decodeBase64 } from "../../crypto/olmlib"; -import { crypto, subtleCrypto, TextEncoder } from "../../crypto/crypto"; -import { generateDecimalSas } from "../../crypto/verification/SASDecimal"; -import { UnstableValue } from "../../NamespacedValue"; -import { EncryptedPayload, MSC3903ECDHPayload, PlainTextPayload } from "./MSC3903ECDHv2RendezvousChannel"; - -/** - * @deprecated Use ECDH_V2 instead - */ -export const ECDH_V1 = new UnstableValue( - "m.rendezvous.v1.curve25519-aes-sha256", - "org.matrix.msc3903.rendezvous.v1.curve25519-aes-sha256", -); - -/** - * @deprecated Use ECDHv2RendezvousCode instead - */ -export interface ECDHv1RendezvousCode extends RendezvousCode { - rendezvous: { - transport: RendezvousTransportDetails; - algorithm: typeof ECDH_V1.name | typeof ECDH_V1.altName; - key: string; - }; -} - -async function importKey(key: Uint8Array): Promise { - if (!subtleCrypto) { - throw new Error("Web Crypto is not available"); - } - - const imported = subtleCrypto.importKey("raw", key, { name: "AES-GCM" }, false, ["encrypt", "decrypt"]); - - return imported; -} - -/** - * Implementation of the unstable [MSC3903](https://github.com/matrix-org/matrix-spec-proposals/pull/3903) - * X25519/ECDH key agreement based secure rendezvous channel. - * Note that this is UNSTABLE and may have breaking changes without notice. - * - * @deprecated Use MSC3903ECDHv2RendezvousChannel instead. This implementation will be removed. - */ -export class MSC3903ECDHv1RendezvousChannel implements RendezvousChannel { - private olmSAS?: SAS; - private ourPublicKey: Uint8Array; - private aesKey?: CryptoKey; - private connected = false; - - public constructor( - private transport: RendezvousTransport, - private theirPublicKey?: Uint8Array, - public onFailure?: (reason: RendezvousFailureReason) => void, - ) { - this.olmSAS = new global.Olm.SAS(); - this.ourPublicKey = decodeBase64(this.olmSAS.get_pubkey()); - } - - public async generateCode(intent: RendezvousIntent): Promise { - if (this.transport.ready) { - throw new Error("Code already generated"); - } - - await this.transport.send({ algorithm: ECDH_V1.name }); - - const rendezvous: ECDHv1RendezvousCode = { - rendezvous: { - algorithm: ECDH_V1.name, - key: encodeBase64(this.ourPublicKey), - transport: await this.transport.details(), - }, - intent, - }; - - return rendezvous; - } - - public async connect(): Promise { - if (this.connected) { - throw new Error("Channel already connected"); - } - - if (!this.olmSAS) { - throw new Error("Channel closed"); - } - - const isInitiator = !this.theirPublicKey; - - if (isInitiator) { - // wait for the other side to send us their public key - const rawRes = await this.transport.receive(); - if (!rawRes) { - throw new Error("No response from other device"); - } - const res = rawRes as Partial; - const { key, algorithm } = res; - if (!algorithm || !ECDH_V1.matches(algorithm) || !key) { - throw new RendezvousError( - "Unsupported algorithm: " + algorithm, - RendezvousFailureReason.UnsupportedAlgorithm, - ); - } - - this.theirPublicKey = decodeBase64(key); - } else { - // send our public key unencrypted - await this.transport.send({ - algorithm: ECDH_V1.name, - key: encodeBase64(this.ourPublicKey), - }); - } - - this.connected = true; - - this.olmSAS.set_their_key(encodeBase64(this.theirPublicKey!)); - - const initiatorKey = isInitiator ? this.ourPublicKey : this.theirPublicKey!; - const recipientKey = isInitiator ? this.theirPublicKey! : this.ourPublicKey; - let aesInfo = ECDH_V1.name; - aesInfo += `|${encodeBase64(initiatorKey)}`; - aesInfo += `|${encodeBase64(recipientKey)}`; - - const aesKeyBytes = this.olmSAS.generate_bytes(aesInfo, 32); - - this.aesKey = await importKey(aesKeyBytes); - - // blank the bytes out to make sure not kept in memory - aesKeyBytes.fill(0); - - const rawChecksum = this.olmSAS.generate_bytes(aesInfo, 5); - return generateDecimalSas(Array.from(rawChecksum)).join("-"); - } - - private async encrypt(data: T): Promise { - if (!subtleCrypto) { - throw new Error("Web Crypto is not available"); - } - - const iv = new Uint8Array(32); - crypto.getRandomValues(iv); - - const encodedData = new TextEncoder().encode(JSON.stringify(data)); - - const ciphertext = await subtleCrypto.encrypt( - { - name: "AES-GCM", - iv, - tagLength: 128, - }, - this.aesKey as CryptoKey, - encodedData, - ); - - return { - iv: encodeBase64(iv), - ciphertext: encodeBase64(ciphertext), - }; - } - - public async send(payload: T): Promise { - if (!this.olmSAS) { - throw new Error("Channel closed"); - } - - if (!this.aesKey) { - throw new Error("Shared secret not set up"); - } - - return this.transport.send(await this.encrypt(payload)); - } - - private async decrypt({ iv, ciphertext }: EncryptedPayload): Promise> { - if (!ciphertext || !iv) { - throw new Error("Missing ciphertext and/or iv"); - } - - const ciphertextBytes = decodeBase64(ciphertext); - - if (!subtleCrypto) { - throw new Error("Web Crypto is not available"); - } - - const plaintext = await subtleCrypto.decrypt( - { - name: "AES-GCM", - iv: decodeBase64(iv), - tagLength: 128, - }, - this.aesKey as CryptoKey, - ciphertextBytes, - ); - - return JSON.parse(new TextDecoder().decode(new Uint8Array(plaintext))); - } - - public async receive(): Promise | undefined> { - if (!this.olmSAS) { - throw new Error("Channel closed"); - } - if (!this.aesKey) { - throw new Error("Shared secret not set up"); - } - - const rawData = await this.transport.receive(); - if (!rawData) { - return undefined; - } - const data = rawData as Partial; - if (data.ciphertext && data.iv) { - return this.decrypt(data as EncryptedPayload); - } - - throw new Error("Data received but no ciphertext"); - } - - public async close(): Promise { - if (this.olmSAS) { - this.olmSAS.free(); - this.olmSAS = undefined; - } - } - - public async cancel(reason: RendezvousFailureReason): Promise { - try { - await this.transport.cancel(reason); - } finally { - await this.close(); - } - } -} diff --git a/src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts b/src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts index 312aaa5c2e3..be60ee5c9aa 100644 --- a/src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts +++ b/src/rendezvous/channels/MSC3903ECDHv2RendezvousChannel.ts @@ -29,7 +29,6 @@ import { encodeUnpaddedBase64, decodeBase64 } from "../../crypto/olmlib"; import { crypto, subtleCrypto, TextEncoder } from "../../crypto/crypto"; import { generateDecimalSas } from "../../crypto/verification/SASDecimal"; import { UnstableValue } from "../../NamespacedValue"; -import { ECDH_V1 } from "./MSC3903ECDHv1RendezvousChannel"; const ECDH_V2 = new UnstableValue( "m.rendezvous.v2.curve25519-aes-sha256", @@ -39,7 +38,7 @@ const ECDH_V2 = new UnstableValue( export interface ECDHv2RendezvousCode extends RendezvousCode { rendezvous: { transport: RendezvousTransportDetails; - algorithm: typeof ECDH_V2.name | typeof ECDH_V2.altName | typeof ECDH_V1.name | typeof ECDH_V1.altName; + algorithm: typeof ECDH_V2.name | typeof ECDH_V2.altName; key: string; }; } @@ -47,7 +46,7 @@ export interface ECDHv2RendezvousCode extends RendezvousCode { export type MSC3903ECDHPayload = PlainTextPayload | EncryptedPayload; export interface PlainTextPayload { - algorithm: typeof ECDH_V2.name | typeof ECDH_V2.altName | typeof ECDH_V1.name | typeof ECDH_V1.altName; + algorithm: typeof ECDH_V2.name | typeof ECDH_V2.altName; key?: string; } diff --git a/src/rendezvous/channels/index.ts b/src/rendezvous/channels/index.ts index 42e0ee15e9e..f157bbeaef1 100644 --- a/src/rendezvous/channels/index.ts +++ b/src/rendezvous/channels/index.ts @@ -14,5 +14,4 @@ See the License for the specific language governing permissions and limitations under the License. */ -export * from "./MSC3903ECDHv1RendezvousChannel"; export * from "./MSC3903ECDHv2RendezvousChannel"; From e782a2afa33032798eba7e92d2b3f28f9baa0564 Mon Sep 17 00:00:00 2001 From: Enrico Schwendig Date: Thu, 2 Mar 2023 17:35:52 +0100 Subject: [PATCH 14/24] Enable group calls without video and audio track by configuration of MatrixClient (#3162) * groupCall: add configuration param to allow no audio and no camera * groupCall: enable datachannel to do no media group calls * groupCall: changed call no media property as object property * groupCall: fix existing unit tests * groupCall: remove not needed flag * groupCall: rename property to allow no media calls * groupCall: mute unmute even without device * groupCall: switch to promise callbacks * groupCall: switch to try catch * test: filter dummy code from coverage * test: extend media mute tests * groupCall: move permission check to device handler * mediaHandler: add error in log statement --- .gitignore | 1 + spec/unit/webrtc/groupCall.spec.ts | 25 ++++++++++-- spec/unit/webrtc/mediaHandler.spec.ts | 10 +++++ src/client.ts | 14 ++++++- src/webrtc/call.ts | 11 +++++- src/webrtc/groupCall.ts | 55 ++++++++++++++++++++++++--- src/webrtc/groupCallEventHandler.ts | 5 ++- src/webrtc/mediaHandler.ts | 18 +++++++-- 8 files changed, 123 insertions(+), 16 deletions(-) diff --git a/.gitignore b/.gitignore index 6bc9edb40a3..98d71fcd60a 100644 --- a/.gitignore +++ b/.gitignore @@ -19,3 +19,4 @@ out .vscode .vscode/ +.idea/ diff --git a/spec/unit/webrtc/groupCall.spec.ts b/spec/unit/webrtc/groupCall.spec.ts index 4b68100113e..02e3a18b495 100644 --- a/spec/unit/webrtc/groupCall.spec.ts +++ b/spec/unit/webrtc/groupCall.spec.ts @@ -109,7 +109,7 @@ const mockGetStateEvents = (type: EventType, userId?: string): MatrixEvent[] | M const ONE_HOUR = 1000 * 60 * 60; const createAndEnterGroupCall = async (cli: MatrixClient, room: Room): Promise => { - const groupCall = new GroupCall(cli, room, GroupCallType.Video, false, GroupCallIntent.Prompt, FAKE_CONF_ID); + const groupCall = new GroupCall(cli, room, GroupCallType.Video, false, GroupCallIntent.Prompt, false, FAKE_CONF_ID); await groupCall.create(); await groupCall.enter(); @@ -135,7 +135,7 @@ describe("Group Call", function () { mockClient = typedMockClient as unknown as MatrixClient; room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1); - groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt); + groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt, false); room.currentState.members[FAKE_USER_ID_1] = { userId: FAKE_USER_ID_1, membership: "join", @@ -484,7 +484,7 @@ describe("Group Call", function () { describe("PTT calls", () => { beforeEach(async () => { // replace groupcall with a PTT one - groupCall = new GroupCall(mockClient, room, GroupCallType.Video, true, GroupCallIntent.Prompt); + groupCall = new GroupCall(mockClient, room, GroupCallType.Video, true, GroupCallIntent.Prompt, false); await groupCall.create(); @@ -647,6 +647,7 @@ describe("Group Call", function () { GroupCallType.Video, false, GroupCallIntent.Prompt, + false, FAKE_CONF_ID, ); @@ -656,6 +657,7 @@ describe("Group Call", function () { GroupCallType.Video, false, GroupCallIntent.Prompt, + false, FAKE_CONF_ID, ); }); @@ -882,11 +884,27 @@ describe("Group Call", function () { expect(await groupCall.setMicrophoneMuted(false)).toBe(false); }); + it("returns false when no permission for audio stream", async () => { + const groupCall = await createAndEnterGroupCall(mockClient, room); + jest.spyOn(mockClient.getMediaHandler(), "getUserMediaStream").mockRejectedValueOnce( + new Error("No Permission"), + ); + expect(await groupCall.setMicrophoneMuted(false)).toBe(false); + }); + it("returns false when unmuting video with no video device", async () => { const groupCall = await createAndEnterGroupCall(mockClient, room); jest.spyOn(mockClient.getMediaHandler(), "hasVideoDevice").mockResolvedValue(false); expect(await groupCall.setLocalVideoMuted(false)).toBe(false); }); + + it("returns false when no permission for video stream", async () => { + const groupCall = await createAndEnterGroupCall(mockClient, room); + jest.spyOn(mockClient.getMediaHandler(), "getUserMediaStream").mockRejectedValueOnce( + new Error("No Permission"), + ); + expect(await groupCall.setLocalVideoMuted(false)).toBe(false); + }); }); describe("remote muting", () => { @@ -1465,6 +1483,7 @@ describe("Group Call", function () { GroupCallType.Video, false, GroupCallIntent.Prompt, + false, FAKE_CONF_ID, ); await groupCall.create(); diff --git a/spec/unit/webrtc/mediaHandler.spec.ts b/spec/unit/webrtc/mediaHandler.spec.ts index 1b3a815b00a..f50baec1f06 100644 --- a/spec/unit/webrtc/mediaHandler.spec.ts +++ b/spec/unit/webrtc/mediaHandler.spec.ts @@ -242,6 +242,11 @@ describe("Media Handler", function () { ); expect(await mediaHandler.hasAudioDevice()).toEqual(false); }); + + it("returns false if the system not permitting access audio inputs", async () => { + mockMediaDevices.enumerateDevices.mockRejectedValueOnce(new Error("No Permission")); + expect(await mediaHandler.hasAudioDevice()).toEqual(false); + }); }); describe("hasVideoDevice", () => { @@ -255,6 +260,11 @@ describe("Media Handler", function () { ); expect(await mediaHandler.hasVideoDevice()).toEqual(false); }); + + it("returns false if the system not permitting access video inputs", async () => { + mockMediaDevices.enumerateDevices.mockRejectedValueOnce(new Error("No Permission")); + expect(await mediaHandler.hasVideoDevice()).toEqual(false); + }); }); describe("getUserMediaStream", () => { diff --git a/src/client.ts b/src/client.ts index d59f5cc5d68..963c244b689 100644 --- a/src/client.ts +++ b/src/client.ts @@ -371,6 +371,13 @@ export interface ICreateClientOpts { * Defaults to a built-in English handler with basic pluralisation. */ roomNameGenerator?: (roomId: string, state: RoomNameState) => string | null; + + /** + * If true, participant can join group call without video and audio this has to be allowed. By default, a local + * media stream is needed to establish a group call. + * Default: false. + */ + isVoipWithNoMediaAllowed?: boolean; } export interface IMatrixClientCreateOpts extends ICreateClientOpts { @@ -1169,6 +1176,7 @@ export class MatrixClient extends TypedEventEmitter; + // Used to allow connection without Video and Audio. To establish a webrtc connection without media a Data channel is + // needed At the moment this property is true if we allow MatrixClient with isVoipWithNoMediaAllowed = true + private readonly isOnlyDataChannelAllowed: boolean; /** * Construct a new Matrix Call. @@ -420,6 +423,8 @@ export class MatrixCall extends TypedEventEmitter { - const devices = await navigator.mediaDevices.enumerateDevices(); - return devices.filter((device) => device.kind === "audioinput").length > 0; + try { + const devices = await navigator.mediaDevices.enumerateDevices(); + return devices.filter((device) => device.kind === "audioinput").length > 0; + } catch (err) { + logger.log(`MediaHandler hasAudioDevice() calling navigator.mediaDevices.enumerateDevices with error`, err); + return false; + } } public async hasVideoDevice(): Promise { - const devices = await navigator.mediaDevices.enumerateDevices(); - return devices.filter((device) => device.kind === "videoinput").length > 0; + try { + const devices = await navigator.mediaDevices.enumerateDevices(); + return devices.filter((device) => device.kind === "videoinput").length > 0; + } catch (err) { + logger.log(`MediaHandler hasVideoDevice() calling navigator.mediaDevices.enumerateDevices with error`, err); + return false; + } } /** From cd526a254dde0697501a7180f9c3aa78b6eb1b91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damir=20Jeli=C4=87?= Date: Thu, 2 Mar 2023 17:38:24 +0100 Subject: [PATCH 15/24] Stop requesting room keys from other users (#2982) * Refactor the room key handling method * Fix the forwarded room key test to use the same user ids. We have some tests that check if receiving a forwarded room key works. These claim to use the same user id, but in fact they change the user id in the last moment before the event is passed into the client. Let's change this so we're always operating with the same user id. * Stop requesting room keys from other users We never accept such room keys, so there isn't a point in requesting them. * fixup! Refactor the room key handling method * Apply suggestions from code review Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> * fixup! Refactor the room key handling method * fixup! Apply suggestions from code review * fixup! Refactor the room key handling method --------- Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> --- spec/unit/crypto.spec.ts | 61 +++-- src/crypto/algorithms/megolm.ts | 444 +++++++++++++++++++++++--------- src/models/event.ts | 12 +- 3 files changed, 365 insertions(+), 152 deletions(-) diff --git a/spec/unit/crypto.spec.ts b/spec/unit/crypto.spec.ts index 43b6fd9f056..ec1c660b7a1 100644 --- a/spec/unit/crypto.spec.ts +++ b/spec/unit/crypto.spec.ts @@ -304,20 +304,24 @@ describe("Crypto", function () { describe("Key requests", function () { let aliceClient: MatrixClient; + let secondAliceClient: MatrixClient; let bobClient: MatrixClient; let claraClient: MatrixClient; beforeEach(async function () { aliceClient = new TestClient("@alice:example.com", "alicedevice").client; + secondAliceClient = new TestClient("@alice:example.com", "secondAliceDevice").client; bobClient = new TestClient("@bob:example.com", "bobdevice").client; claraClient = new TestClient("@clara:example.com", "claradevice").client; await aliceClient.initCrypto(); + await secondAliceClient.initCrypto(); await bobClient.initCrypto(); await claraClient.initCrypto(); }); afterEach(async function () { aliceClient.stopClient(); + secondAliceClient.stopClient(); bobClient.stopClient(); claraClient.stopClient(); }); @@ -568,17 +572,17 @@ describe("Crypto", function () { expect(aliceSendToDevice.mock.calls[2][2]).not.toBe(txnId); }); - it("should accept forwarded keys which it requested", async function () { + it("should accept forwarded keys it requested from one of its own user's other devices", async function () { const encryptionCfg = { algorithm: "m.megolm.v1.aes-sha2", }; const roomId = "!someroom"; const aliceRoom = new Room(roomId, aliceClient, "@alice:example.com", {}); - const bobRoom = new Room(roomId, bobClient, "@bob:example.com", {}); + const bobRoom = new Room(roomId, secondAliceClient, "@alice:example.com", {}); aliceClient.store.storeRoom(aliceRoom); - bobClient.store.storeRoom(bobRoom); + secondAliceClient.store.storeRoom(bobRoom); await aliceClient.setRoomEncryption(roomId, encryptionCfg); - await bobClient.setRoomEncryption(roomId, encryptionCfg); + await secondAliceClient.setRoomEncryption(roomId, encryptionCfg); const events = [ new MatrixEvent({ type: "m.room.message", @@ -614,7 +618,7 @@ describe("Crypto", function () { // @ts-ignore private properties event.claimedEd25519Key = null; try { - await bobClient.crypto!.decryptEvent(event); + await secondAliceClient.crypto!.decryptEvent(event); } catch (e) { // we expect this to fail because we don't have the // decryption keys yet @@ -623,10 +627,11 @@ describe("Crypto", function () { ); const device = new DeviceInfo(aliceClient.deviceId!); - bobClient.crypto!.deviceList.getDeviceByIdentityKey = () => device; - bobClient.crypto!.deviceList.getUserByIdentityKey = () => "@alice:example.com"; + device.verified = DeviceInfo.DeviceVerification.VERIFIED; + secondAliceClient.crypto!.deviceList.getDeviceByIdentityKey = () => device; + secondAliceClient.crypto!.deviceList.getUserByIdentityKey = () => "@alice:example.com"; - const cryptoStore = bobClient.crypto!.cryptoStore; + const cryptoStore = secondAliceClient.crypto!.cryptoStore; const eventContent = events[0].getWireContent(); const senderKey = eventContent.sender_key; const sessionId = eventContent.session_id; @@ -642,7 +647,7 @@ describe("Crypto", function () { state: RoomKeyRequestState.Sent, }); - const bobDecryptor = bobClient.crypto!.getRoomDecryptor(roomId, olmlib.MEGOLM_ALGORITHM); + const bobDecryptor = secondAliceClient.crypto!.getRoomDecryptor(roomId, olmlib.MEGOLM_ALGORITHM); const decryptEventsPromise = Promise.all( events.map((ev) => { @@ -651,7 +656,7 @@ describe("Crypto", function () { ); const ksEvent = await keyshareEventForEvent(aliceClient, events[0], 0); await bobDecryptor.onRoomKeyEvent(ksEvent); - const key = await bobClient.crypto!.olmDevice.getInboundGroupSessionKey( + const key = await secondAliceClient.crypto!.olmDevice.getInboundGroupSessionKey( roomId, events[0].getWireContent().sender_key, events[0].getWireContent().session_id, @@ -755,7 +760,7 @@ describe("Crypto", function () { expect(events[1].getContent().msgtype).not.toBe("m.bad.encrypted"); }); - it("should accept forwarded keys from one of its own user's other devices", async function () { + it("should not accept requested forwarded keys from other users", async function () { const encryptionCfg = { algorithm: "m.megolm.v1.aes-sha2", }; @@ -809,31 +814,39 @@ describe("Crypto", function () { }), ); - const device = new DeviceInfo(claraClient.deviceId!); + const cryptoStore = bobClient.crypto!.cryptoStore; + const eventContent = events[0].getWireContent(); + const senderKey = eventContent.sender_key; + const sessionId = eventContent.session_id; + const roomKeyRequestBody = { + algorithm: olmlib.MEGOLM_ALGORITHM, + room_id: roomId, + sender_key: senderKey, + session_id: sessionId, + }; + const outgoingReq = await cryptoStore.getOutgoingRoomKeyRequest(roomKeyRequestBody); + expect(outgoingReq).toBeDefined(); + await cryptoStore.updateOutgoingRoomKeyRequest(outgoingReq!.requestId, RoomKeyRequestState.Unsent, { + state: RoomKeyRequestState.Sent, + }); + + const device = new DeviceInfo(aliceClient.deviceId!); device.verified = DeviceInfo.DeviceVerification.VERIFIED; bobClient.crypto!.deviceList.getDeviceByIdentityKey = () => device; - bobClient.crypto!.deviceList.getUserByIdentityKey = () => "@bob:example.com"; + bobClient.crypto!.deviceList.getUserByIdentityKey = () => "@alice:example.com"; const bobDecryptor = bobClient.crypto!.getRoomDecryptor(roomId, olmlib.MEGOLM_ALGORITHM); - const decryptEventsPromise = Promise.all( - events.map((ev) => { - return awaitEvent(ev, "Event.decrypted"); - }), - ); const ksEvent = await keyshareEventForEvent(aliceClient, events[0], 0); - ksEvent.event.sender = bobClient.getUserId()!; - ksEvent.sender = new RoomMember(roomId, bobClient.getUserId()!); + ksEvent.event.sender = aliceClient.getUserId()!; + ksEvent.sender = new RoomMember(roomId, aliceClient.getUserId()!); await bobDecryptor.onRoomKeyEvent(ksEvent); const key = await bobClient.crypto!.olmDevice.getInboundGroupSessionKey( roomId, events[0].getWireContent().sender_key, events[0].getWireContent().session_id, ); - expect(key).not.toBeNull(); - await decryptEventsPromise; - expect(events[0].getContent().msgtype).not.toBe("m.bad.encrypted"); - expect(events[1].getContent().msgtype).not.toBe("m.bad.encrypted"); + expect(key).toBeNull(); }); it("should not accept unexpected forwarded keys for a room it's in", async function () { diff --git a/src/crypto/algorithms/megolm.ts b/src/crypto/algorithms/megolm.ts index 3037dec1351..934b69bd35d 100644 --- a/src/crypto/algorithms/megolm.ts +++ b/src/crypto/algorithms/megolm.ts @@ -74,6 +74,30 @@ export interface IOlmDevice { deviceInfo: T; } +/** The result of parsing the an `m.room_key` or `m.forwarded_room_key` to-device event */ +interface RoomKey { + /** + * The Curve25519 key of the megolm session creator. + * + * For `m.room_key`, this is also the sender of the `m.room_key` to-device event. + * For `m.forwarded_room_key`, the two are different (and the key of the sender of the + * `m.forwarded_room_key` event is included in `forwardingKeyChain`) + */ + senderKey: string; + sessionId: string; + sessionKey: string; + exportFormat: boolean; + roomId: string; + algorithm: string; + /** + * A list of the curve25519 keys of the users involved in forwarding this key, most recent last. + * For `m.room_key` events, this is empty. + */ + forwardingKeyChain: string[]; + keysClaimed: Partial>; + extraSessionData: OlmGroupSessionExtraData; +} + export interface IOutboundGroupSessionKey { chain_index: number; key: string; @@ -1475,13 +1499,20 @@ export class MegolmDecryption extends DecryptionAlgorithm { } } - public async onRoomKeyEvent(event: MatrixEvent): Promise { + /** + * Parse a RoomKey out of an `m.room_key` event. + * + * @param event - the event containing the room key. + * + * @returns The `RoomKey` if it could be successfully parsed out of the + * event. + * + * @internal + * + */ + private roomKeyFromEvent(event: MatrixEvent): RoomKey | undefined { + const senderKey = event.getSenderKey()!; const content = event.getContent>(); - let senderKey = event.getSenderKey()!; - let forwardingKeyChain: string[] = []; - let exportFormat = false; - let keysClaimed: ReturnType; - const extraSessionData: OlmGroupSessionExtraData = {}; if (!content.room_id || !content.session_key || !content.session_id || !content.algorithm) { @@ -1498,154 +1529,331 @@ export class MegolmDecryption extends DecryptionAlgorithm { extraSessionData.sharedHistory = true; } - if (event.getType() == "m.forwarded_room_key") { - const deviceInfo = this.crypto.deviceList.getDeviceByIdentityKey(olmlib.OLM_ALGORITHM, senderKey); - const senderKeyUser = this.baseApis.crypto!.deviceList.getUserByIdentityKey( - olmlib.OLM_ALGORITHM, - senderKey, - ); - if (senderKeyUser !== event.getSender()) { - this.prefixedLogger.error("sending device does not belong to the user it claims to be from"); - return; - } - const outgoingRequests = deviceInfo - ? await this.crypto.cryptoStore.getOutgoingRoomKeyRequestsByTarget( - event.getSender()!, - deviceInfo.deviceId, - [RoomKeyRequestState.Sent], - ) - : []; - const weRequested = outgoingRequests.some( - (req) => - req.requestBody.room_id === content.room_id && req.requestBody.session_id === content.session_id, - ); - const room = this.baseApis.getRoom(content.room_id); - const memberEvent = room?.getMember(this.userId)?.events.member; - const fromInviter = - memberEvent?.getSender() === event.getSender() || - (memberEvent?.getUnsigned()?.prev_sender === event.getSender() && - memberEvent?.getPrevContent()?.membership === "invite"); - const fromUs = event.getSender() === this.baseApis.getUserId(); - - if (!weRequested && !fromUs) { - // If someone sends us an unsolicited key and they're - // not one of our other devices and it's not shared - // history, ignore it - if (!extraSessionData.sharedHistory) { - this.prefixedLogger.log("forwarded key not shared history - ignoring"); - return; - } + const roomKey: RoomKey = { + senderKey: senderKey, + sessionId: content.session_id, + sessionKey: content.session_key, + extraSessionData, + exportFormat: false, + roomId: content.room_id, + algorithm: content.algorithm, + forwardingKeyChain: [], + keysClaimed: event.getKeysClaimed(), + }; - // If someone sends us an unsolicited key for a room - // we're already in, and they're not one of our other - // devices or the one who invited us, ignore it - if (room && !fromInviter) { - this.prefixedLogger.log("forwarded key not from inviter or from us - ignoring"); - return; - } - } + return roomKey; + } - exportFormat = true; - forwardingKeyChain = Array.isArray(content.forwarding_curve25519_key_chain) - ? content.forwarding_curve25519_key_chain - : []; + /** + * Parse a RoomKey out of an `m.forwarded_room_key` event. + * + * @param event - the event containing the forwarded room key. + * + * @returns The `RoomKey` if it could be successfully parsed out of the + * event. + * + * @internal + * + */ + private forwardedRoomKeyFromEvent(event: MatrixEvent): RoomKey | undefined { + // the properties in m.forwarded_room_key are a superset of those in m.room_key, so + // start by parsing the m.room_key fields. + const roomKey = this.roomKeyFromEvent(event); - // copy content before we modify it - forwardingKeyChain = forwardingKeyChain.slice(); - forwardingKeyChain.push(senderKey); + if (!roomKey) { + return; + } - if (!content.sender_key) { - this.prefixedLogger.error("forwarded_room_key event is missing sender_key field"); - return; - } + const senderKey = event.getSenderKey()!; + const content = event.getContent>(); - const ed25519Key = content.sender_claimed_ed25519_key; - if (!ed25519Key) { - this.prefixedLogger.error(`forwarded_room_key_event is missing sender_claimed_ed25519_key field`); - return; - } + const senderKeyUser = this.baseApis.crypto!.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey); - keysClaimed = { - ed25519: ed25519Key, - }; + // We received this to-device event from event.getSenderKey(), but the original + // creator of the room key is claimed in the content. + const claimedCurve25519Key = content.sender_key; + const claimedEd25519Key = content.sender_claimed_ed25519_key; - // If this is a key for a room we're not in, don't load it - // yet, just park it in case *this sender* invites us to - // that room later - if (!room) { - const parkedData = { - senderId: event.getSender()!, - senderKey: content.sender_key, - sessionId: content.session_id, - sessionKey: content.session_key, - keysClaimed, - forwardingCurve25519KeyChain: forwardingKeyChain, - }; - await this.crypto.cryptoStore.doTxn( - "readwrite", - ["parked_shared_history"], - (txn) => this.crypto.cryptoStore.addParkedSharedHistory(content.room_id!, parkedData, txn), - this.prefixedLogger.withPrefix("[addParkedSharedHistory]"), - ); - return; - } + let forwardingKeyChain = Array.isArray(content.forwarding_curve25519_key_chain) + ? content.forwarding_curve25519_key_chain + : []; - const sendingDevice = - this.crypto.deviceList.getDeviceByIdentityKey(olmlib.OLM_ALGORITHM, senderKey) ?? undefined; - const deviceTrust = this.crypto.checkDeviceInfoTrust(event.getSender()!, sendingDevice); + // copy content before we modify it + forwardingKeyChain = forwardingKeyChain.slice(); + forwardingKeyChain.push(senderKey); - if (fromUs && !deviceTrust.isVerified()) { - return; - } + // Check if we have all the fields we need. + if (senderKeyUser !== event.getSender()) { + this.prefixedLogger.error("sending device does not belong to the user it claims to be from"); + return; + } - // forwarded keys are always untrusted - extraSessionData.untrusted = true; + if (!claimedCurve25519Key) { + this.prefixedLogger.error("forwarded_room_key event is missing sender_key field"); + return; + } + + if (!claimedEd25519Key) { + this.prefixedLogger.error(`forwarded_room_key_event is missing sender_claimed_ed25519_key field`); + return; + } + + const keysClaimed = { + ed25519: claimedEd25519Key, + }; + + // FIXME: We're reusing the same field to track both: + // + // 1. The Olm identity we've received this room key from. + // 2. The Olm identity deduced (in the trusted case) or claiming (in the + // untrusted case) to be the original creator of this room key. + // + // We now overwrite the value tracking usage 1 with the value tracking usage 2. + roomKey.senderKey = claimedCurve25519Key; + // Replace our keysClaimed as well. + roomKey.keysClaimed = keysClaimed; + roomKey.exportFormat = true; + roomKey.forwardingKeyChain = forwardingKeyChain; + // forwarded keys are always untrusted + roomKey.extraSessionData.untrusted = true; + + return roomKey; + } - // replace the sender key with the sender key of the session - // creator for storage - senderKey = content.sender_key; + /** + * Determine if we should accept the forwarded room key that was found in the given + * event. + * + * @param event - An `m.forwarded_room_key` event. + * @param roomKey - The room key that was found in the event. + * + * @returns promise that will resolve to a boolean telling us if it's ok to + * accept the given forwarded room key. + * + * @internal + * + */ + private async shouldAcceptForwardedKey(event: MatrixEvent, roomKey: RoomKey): Promise { + const senderKey = event.getSenderKey()!; + + const sendingDevice = + this.crypto.deviceList.getDeviceByIdentityKey(olmlib.OLM_ALGORITHM, senderKey) ?? undefined; + const deviceTrust = this.crypto.checkDeviceInfoTrust(event.getSender()!, sendingDevice); + + // Using the plaintext sender here is fine since we checked that the + // sender matches to the user id in the device keys when this event was + // originally decrypted. This can obviously only happen if the device + // keys have been downloaded, but if they haven't the + // `deviceTrust.isVerified()` flag would be false as well. + // + // It would still be far nicer if the `sendingDevice` had a user ID + // attached to it that went through signature checks. + const fromUs = event.getSender() === this.baseApis.getUserId(); + const keyFromOurVerifiedDevice = deviceTrust.isVerified() && fromUs; + const weRequested = await this.wasRoomKeyRequested(event, roomKey); + const fromInviter = this.wasRoomKeyForwardedByInviter(event, roomKey); + const sharedAsHistory = this.wasRoomKeyForwardedAsHistory(roomKey); + + return (weRequested && keyFromOurVerifiedDevice) || (fromInviter && sharedAsHistory); + } + + /** + * Did we ever request the given room key from the event sender and its + * accompanying device. + * + * @param event - An `m.forwarded_room_key` event. + * @param roomKey - The room key that was found in the event. + * + * @internal + * + */ + private async wasRoomKeyRequested(event: MatrixEvent, roomKey: RoomKey): Promise { + // We send the `m.room_key_request` out as a wildcard to-device request, + // otherwise we would have to duplicate the same content for each + // device. This is why we need to pass in "*" as the device id here. + const outgoingRequests = await this.crypto.cryptoStore.getOutgoingRoomKeyRequestsByTarget( + event.getSender()!, + "*", + [RoomKeyRequestState.Sent], + ); + + return outgoingRequests.some( + (req) => req.requestBody.room_id === roomKey.roomId && req.requestBody.session_id === roomKey.sessionId, + ); + } + + private wasRoomKeyForwardedByInviter(event: MatrixEvent, roomKey: RoomKey): boolean { + // TODO: This is supposed to have a time limit. We should only accept + // such keys if we happen to receive them for a recently joined room. + const room = this.baseApis.getRoom(roomKey.roomId); + const senderKey = event.getSenderKey(); + + if (!senderKey) { + return false; + } + + const senderKeyUser = this.crypto.deviceList.getUserByIdentityKey(olmlib.OLM_ALGORITHM, senderKey); + + if (!senderKeyUser) { + return false; + } + + const memberEvent = room?.getMember(this.userId)?.events.member; + const fromInviter = + memberEvent?.getSender() === senderKeyUser || + (memberEvent?.getUnsigned()?.prev_sender === senderKeyUser && + memberEvent?.getPrevContent()?.membership === "invite"); + + if (room && fromInviter) { + return true; } else { - keysClaimed = event.getKeysClaimed(); + return false; } + } - if (content["org.matrix.msc3061.shared_history"]) { - extraSessionData.sharedHistory = true; + private wasRoomKeyForwardedAsHistory(roomKey: RoomKey): boolean { + const room = this.baseApis.getRoom(roomKey.roomId); + + // If the key is not for a known room, then something fishy is going on, + // so we reject the key out of caution. In practice, this is a bit moot + // because we'll only accept shared_history forwarded by the inviter, and + // we won't know who was the inviter for an unknown room, so we'll reject + // it anyway. + if (room && roomKey.extraSessionData.sharedHistory) { + return true; + } else { + return false; } + } + + /** + * Check if a forwarded room key should be parked. + * + * A forwarded room key should be parked if it's a key for a room we're not + * in. We park the forwarded room key in case *this sender* invites us to + * that room later. + */ + private shouldParkForwardedKey(roomKey: RoomKey): boolean { + const room = this.baseApis.getRoom(roomKey.roomId); + if (!room && roomKey.extraSessionData.sharedHistory) { + return true; + } else { + return false; + } + } + + /** + * Park the given room key to our store. + * + * @param event - An `m.forwarded_room_key` event. + * @param roomKey - The room key that was found in the event. + * + * @internal + * + */ + private async parkForwardedKey(event: MatrixEvent, roomKey: RoomKey): Promise { + const parkedData = { + senderId: event.getSender()!, + senderKey: roomKey.senderKey, + sessionId: roomKey.sessionId, + sessionKey: roomKey.sessionKey, + keysClaimed: roomKey.keysClaimed, + forwardingCurve25519KeyChain: roomKey.forwardingKeyChain, + }; + await this.crypto.cryptoStore.doTxn( + "readwrite", + ["parked_shared_history"], + (txn) => this.crypto.cryptoStore.addParkedSharedHistory(roomKey.roomId, parkedData, txn), + logger.withPrefix("[addParkedSharedHistory]"), + ); + } + + /** + * Add the given room key to our store. + * + * @param roomKey - The room key that should be added to the store. + * + * @internal + * + */ + private async addRoomKey(roomKey: RoomKey): Promise { try { await this.olmDevice.addInboundGroupSession( - content.room_id, - senderKey, - forwardingKeyChain, - content.session_id, - content.session_key, - keysClaimed, - exportFormat, - extraSessionData, + roomKey.roomId, + roomKey.senderKey, + roomKey.forwardingKeyChain, + roomKey.sessionId, + roomKey.sessionKey, + roomKey.keysClaimed, + roomKey.exportFormat, + roomKey.extraSessionData, ); // have another go at decrypting events sent with this session. - if (await this.retryDecryption(senderKey, content.session_id, !extraSessionData.untrusted)) { + if (await this.retryDecryption(roomKey.senderKey, roomKey.sessionId, !roomKey.extraSessionData.untrusted)) { // cancel any outstanding room key requests for this session. // Only do this if we managed to decrypt every message in the // session, because if we didn't, we leave the other key // requests in the hopes that someone sends us a key that // includes an earlier index. this.crypto.cancelRoomKeyRequest({ - algorithm: content.algorithm, - room_id: content.room_id, - session_id: content.session_id, - sender_key: senderKey, + algorithm: roomKey.algorithm, + room_id: roomKey.roomId, + session_id: roomKey.sessionId, + sender_key: roomKey.senderKey, }); } // don't wait for the keys to be backed up for the server - await this.crypto.backupManager.backupGroupSession(senderKey, content.session_id); + await this.crypto.backupManager.backupGroupSession(roomKey.senderKey, roomKey.sessionId); } catch (e) { this.prefixedLogger.error(`Error handling m.room_key_event: ${e}`); } } + /** + * Handle room keys that have been forwarded to us as an + * `m.forwarded_room_key` event. + * + * Forwarded room keys need special handling since we have no way of knowing + * who the original creator of the room key was. This naturally means that + * forwarded room keys are always untrusted and should only be accepted in + * some cases. + * + * @param event - An `m.forwarded_room_key` event. + * + * @internal + * + */ + private async onForwardedRoomKey(event: MatrixEvent): Promise { + const roomKey = this.forwardedRoomKeyFromEvent(event); + + if (!roomKey) { + return; + } + + if (await this.shouldAcceptForwardedKey(event, roomKey)) { + await this.addRoomKey(roomKey); + } else if (this.shouldParkForwardedKey(roomKey)) { + await this.parkForwardedKey(event, roomKey); + } + } + + public async onRoomKeyEvent(event: MatrixEvent): Promise { + if (event.getType() == "m.forwarded_room_key") { + await this.onForwardedRoomKey(event); + } else { + const roomKey = this.roomKeyFromEvent(event); + + if (!roomKey) { + return; + } + + await this.addRoomKey(roomKey); + } + } + /** * @param event - key event */ diff --git a/src/models/event.ts b/src/models/event.ts index d6623ae3f97..0ad2b5c182f 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -793,22 +793,14 @@ export class MatrixEvent extends TypedEventEmitter Date: Thu, 2 Mar 2023 19:55:09 +0100 Subject: [PATCH 16/24] groupCall: make no media call param optional (#3186) - ensure group call backwards-compatibility and move `allowCallWithoutVideoAndAudio`to the end of the `CroupCall` constructor --- spec/unit/webrtc/groupCall.spec.ts | 9 +++------ src/client.ts | 2 +- src/webrtc/groupCall.ts | 4 +++- src/webrtc/groupCallEventHandler.ts | 2 +- 4 files changed, 8 insertions(+), 9 deletions(-) diff --git a/spec/unit/webrtc/groupCall.spec.ts b/spec/unit/webrtc/groupCall.spec.ts index 02e3a18b495..9743b332e14 100644 --- a/spec/unit/webrtc/groupCall.spec.ts +++ b/spec/unit/webrtc/groupCall.spec.ts @@ -109,7 +109,7 @@ const mockGetStateEvents = (type: EventType, userId?: string): MatrixEvent[] | M const ONE_HOUR = 1000 * 60 * 60; const createAndEnterGroupCall = async (cli: MatrixClient, room: Room): Promise => { - const groupCall = new GroupCall(cli, room, GroupCallType.Video, false, GroupCallIntent.Prompt, false, FAKE_CONF_ID); + const groupCall = new GroupCall(cli, room, GroupCallType.Video, false, GroupCallIntent.Prompt, FAKE_CONF_ID); await groupCall.create(); await groupCall.enter(); @@ -135,7 +135,7 @@ describe("Group Call", function () { mockClient = typedMockClient as unknown as MatrixClient; room = new Room(FAKE_ROOM_ID, mockClient, FAKE_USER_ID_1); - groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt, false); + groupCall = new GroupCall(mockClient, room, GroupCallType.Video, false, GroupCallIntent.Prompt); room.currentState.members[FAKE_USER_ID_1] = { userId: FAKE_USER_ID_1, membership: "join", @@ -484,7 +484,7 @@ describe("Group Call", function () { describe("PTT calls", () => { beforeEach(async () => { // replace groupcall with a PTT one - groupCall = new GroupCall(mockClient, room, GroupCallType.Video, true, GroupCallIntent.Prompt, false); + groupCall = new GroupCall(mockClient, room, GroupCallType.Video, true, GroupCallIntent.Prompt); await groupCall.create(); @@ -647,7 +647,6 @@ describe("Group Call", function () { GroupCallType.Video, false, GroupCallIntent.Prompt, - false, FAKE_CONF_ID, ); @@ -657,7 +656,6 @@ describe("Group Call", function () { GroupCallType.Video, false, GroupCallIntent.Prompt, - false, FAKE_CONF_ID, ); }); @@ -1483,7 +1481,6 @@ describe("Group Call", function () { GroupCallType.Video, false, GroupCallIntent.Prompt, - false, FAKE_CONF_ID, ); await groupCall.create(); diff --git a/src/client.ts b/src/client.ts index 963c244b689..8f861892a69 100644 --- a/src/client.ts +++ b/src/client.ts @@ -1897,10 +1897,10 @@ export class MatrixClient extends TypedEventEmitter>(); // user_id -> device_id -> MatrixCall private callHandlers = new Map>(); // user_id -> device_id -> ICallHandlers @@ -216,10 +217,10 @@ export class GroupCall extends TypedEventEmitter< public type: GroupCallType, public isPtt: boolean, public intent: GroupCallIntent, - public readonly allowCallWithoutVideoAndAudio: boolean, groupCallId?: string, private dataChannelsEnabled?: boolean, private dataChannelOptions?: IGroupCallDataChannelOptions, + isCallWithoutVideoAndAudio?: boolean, ) { super(); this.reEmitter = new ReEmitter(this); @@ -232,6 +233,7 @@ export class GroupCall extends TypedEventEmitter< this.on(GroupCallEvent.ParticipantsChanged, this.onParticipantsChanged); this.on(GroupCallEvent.GroupCallStateChanged, this.onStateChanged); this.on(GroupCallEvent.LocalScreenshareStateChanged, this.onLocalFeedsChanged); + this.allowCallWithoutVideoAndAudio = !!isCallWithoutVideoAndAudio; } public async create(): Promise { diff --git a/src/webrtc/groupCallEventHandler.ts b/src/webrtc/groupCallEventHandler.ts index 7392a75adab..7be97771447 100644 --- a/src/webrtc/groupCallEventHandler.ts +++ b/src/webrtc/groupCallEventHandler.ts @@ -183,12 +183,12 @@ export class GroupCallEventHandler { callType, isPtt, callIntent, - this.client.isVoipWithNoMediaAllowed, groupCallId, // Because without Media section a WebRTC connection is not possible, so need a RTCDataChannel to set up a // no media WebRTC connection anyway. content?.dataChannelsEnabled || this.client.isVoipWithNoMediaAllowed, dataChannelOptions, + this.client.isVoipWithNoMediaAllowed, ); this.groupCalls.set(room.roomId, groupCall); From 585ce072609c2413c4db80cc5918dcd438e53a74 Mon Sep 17 00:00:00 2001 From: Richard van der Hoff <1389908+richvdh@users.noreply.github.com> Date: Fri, 3 Mar 2023 10:18:45 +0000 Subject: [PATCH 17/24] Stub out the rust crypto implementation for browserify (#3187) Fixes #3182. --- package.json | 23 +++++- src/rust-crypto/browserify-index.ts | 31 ++++++++ yarn.lock | 111 ++++++++++++++++++++++++++++ 3 files changed, 164 insertions(+), 1 deletion(-) create mode 100644 src/rust-crypto/browserify-index.ts diff --git a/package.json b/package.json index 7e4c2f7d90f..1a7b58490e7 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,7 @@ "build:dev": "yarn clean && git rev-parse HEAD > git-revision.txt && yarn build:compile && yarn build:types", "build:types": "tsc -p tsconfig-build.json --emitDeclarationOnly", "build:compile": "babel -d lib --verbose --extensions \".ts,.js\" src", - "build:compile-browser": "mkdir dist && browserify -d src/browser-index.ts -p [ tsify -p ./tsconfig-build.json ] -t [ babelify --sourceMaps=inline --presets [ @babel/preset-env @babel/preset-typescript ] ] | exorcist dist/browser-matrix.js.map > dist/browser-matrix.js", + "build:compile-browser": "mkdir dist && BROWSERIFYSWAP_ENV='no-rust-crypto' browserify -d src/browser-index.ts -p [ tsify -p ./tsconfig-build.json ] | exorcist dist/browser-matrix.js.map > dist/browser-matrix.js", "build:minify-browser": "terser dist/browser-matrix.js --compress --mangle --source-map --output dist/browser-matrix.min.js", "gendoc": "typedoc", "lint": "yarn lint:types && yarn lint:js", @@ -97,6 +97,7 @@ "babelify": "^10.0.0", "better-docs": "^2.4.0-beta.9", "browserify": "^17.0.0", + "browserify-swap": "^0.2.2", "debug": "^4.3.4", "docdash": "^2.0.0", "domexception": "^4.0.0", @@ -147,5 +148,25 @@ "outputDirectory": "coverage", "outputName": "jest-sonar-report.xml", "relativePaths": true + }, + "browserify": { + "transform": [ + "browserify-swap", + [ + "babelify", + { + "sourceMaps": "inline", + "presets": [ + "@babel/preset-env", + "@babel/preset-typescript" + ] + } + ] + ] + }, + "browserify-swap": { + "no-rust-crypto": { + "src/rust-crypto/index.ts$": "./src/rust-crypto/browserify-index.ts" + } } } diff --git a/src/rust-crypto/browserify-index.ts b/src/rust-crypto/browserify-index.ts new file mode 100644 index 00000000000..7f91e90628e --- /dev/null +++ b/src/rust-crypto/browserify-index.ts @@ -0,0 +1,31 @@ +/* +Copyright 2023 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* This file replaces rust-crypto/index.ts when the js-sdk is being built for browserify. + * + * It is a stub, so that we do not import the whole of the base64'ed wasm artifact into the browserify bundle. + * It deliberately does nothing except raise an exception. + */ + +import { IHttpOpts, MatrixHttpApi } from "../http-api"; + +export async function initRustCrypto( + _http: MatrixHttpApi, + _userId: string, + _deviceId: string, +): Promise { + throw new Error("Rust crypto is not supported under browserify."); +} diff --git a/yarn.lock b/yarn.lock index 1e138046ae5..a1a0cb9b802 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2184,6 +2184,11 @@ ansi-styles@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-5.2.0.tgz#07449690ad45777d1924ac2abb2fc8895dba836b" integrity sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA== +ansicolors@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" + integrity sha512-QXu7BPrP29VllRxH8GwB7x5iX5qWKAAMLqKQGWTeLWVlNHNOpVMJ91dsxQAIWXpjuW5wqvxu3Jd/nRjrJ+0pqg== + any-promise@^1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" @@ -2568,6 +2573,16 @@ browserify-sign@^4.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" +browserify-swap@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/browserify-swap/-/browserify-swap-0.2.2.tgz#a982541fde5f9bfaa3519c9582ccc48d6c1e33b6" + integrity sha512-3Gu8HcfzBscN9Z/87pVamlvoVL1SobstVovHQLTzqQrX8NpeoPJPOXSUZqDCChxgTdlWZnbARx/J/pd7ArIOdw== + dependencies: + find-parent-dir "~0.1.0" + resolve "~0.6.1" + through2 "~0.2.3" + viralify "~0.4.1" + browserify-zlib@~0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" @@ -3923,6 +3938,11 @@ find-cache-dir@^2.0.0: make-dir "^2.0.0" pkg-dir "^3.0.0" +find-parent-dir@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/find-parent-dir/-/find-parent-dir-0.1.0.tgz#101b8eca4fb27b94263187a2fadc56b95caa87d4" + integrity sha512-EFR3+F3hYBSGnZZuC7dQIlkIbPXdsFz1+dRMjNRrabkEK5WCZbbNFFuh/pbHKDnSc/THW98LU+kSTRIbvUecYw== + find-up@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-3.0.0.tgz#49169f1d7993430646da61ecc5ae355c21c97b73" @@ -4096,6 +4116,14 @@ glob@^7.1.0, glob@^7.1.3, glob@^7.1.4, glob@^7.2.0: once "^1.3.0" path-is-absolute "^1.0.0" +glob@~3.2.7: + version "3.2.11" + resolved "https://registry.yarnpkg.com/glob/-/glob-3.2.11.tgz#4a973f635b9190f715d10987d5c00fd2815ebe3d" + integrity sha512-hVb0zwEZwC1FXSKRPFTeOtN7AArJcJlI6ULGLtrstaswKNlrTJqAA+1lYlSUop4vjA423xlBzqfVS3iWGlqJ+g== + dependencies: + inherits "2" + minimatch "0.3" + globals@^11.1.0: version "11.12.0" resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e" @@ -4619,6 +4647,11 @@ is-wsl@^2.2.0: dependencies: is-docker "^2.0.0" +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + integrity sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ== + isarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" @@ -5422,6 +5455,11 @@ loose-envify@^1.4.0: dependencies: js-tokens "^3.0.0 || ^4.0.0" +lru-cache@2: + version "2.7.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-2.7.3.tgz#6d4524e8b955f95d4f5b58851ce21dd72fb4e952" + integrity sha512-WpibWJ60c3AgAz8a2iYErDrcT2C7OmKnsWhIcHOjkUHFjkXncJhtLxNSqUmxRxRunpb5I8Vprd7aNSd2NtksJQ== + lru-cache@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" @@ -5584,6 +5622,14 @@ minimalistic-crypto-utils@^1.0.1: resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" integrity sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg== +minimatch@0.3: + version "0.3.0" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-0.3.0.tgz#275d8edaac4f1bb3326472089e7949c8394699dd" + integrity sha512-WFX1jI1AaxNTZVOHLBVazwTWKaQjoykSzCBNXB72vDTCzopQGtyP91tKdFK5cv1+qMwPyiTu1HqUriqplI8pcA== + dependencies: + lru-cache "2" + sigmund "~1.0.0" + minimatch@^3.0.2, minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.1.2.tgz#19cd194bfd3e428f049a70817c038d89ab4be35b" @@ -5598,6 +5644,11 @@ minimatch@^6.1.6: dependencies: brace-expansion "^2.0.1" +minimist@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.5.tgz#d7aa327bcecf518f9106ac6b8f003fa3bcea8566" + integrity sha512-rSJ0cdmCj3qmKdObcnMcWgPVOyaOWlazLhZAJW0s6G6lx1ZEuFkraWmEH5LTvX90btkfHPclQBjvjU7A/kYRFg== + minimist@^1.1.0, minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: version "1.2.7" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.7.tgz#daa1c4d91f507390437c6a8bc01078e7000c4d18" @@ -5738,6 +5789,11 @@ object-keys@^1.1.1: resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e" integrity sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA== +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + integrity sha512-ncrLw+X55z7bkl5PnUvHwFK9FcGuFYo9gtjws2XtSzL+aZ8tm830P60WJ0dSmFVaSalWieW5MD7kEdnXda9yJw== + object.assign@^4.1.4: version "4.1.4" resolved "https://registry.yarnpkg.com/object.assign/-/object.assign-4.1.4.tgz#9673c7c7c351ab8c4d0b516f4343ebf4dfb7799f" @@ -6374,6 +6430,16 @@ readable-stream@^3.5.0, readable-stream@^3.6.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + integrity sha512-+MeVjFf4L44XUkhM1eYbD8fyEsxcV81pqMSR5gblfcLCHfZvbrqy4/qYHE+/R5HoBUT11WV5O08Cr1n3YXkWVQ== + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -6518,6 +6584,11 @@ resolve@^1.1.4, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.17. path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +resolve@~0.6.1: + version "0.6.3" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-0.6.3.tgz#dd957982e7e736debdf53b58a4dd91754575dd46" + integrity sha512-UHBY3viPlJKf85YijDUcikKX6tmF4SokIDp518ZDVT92JNDcG5uKIthaT/owt3Sar0lwtOafsQuwrg22/v2Dwg== + resolve@~1.19.0: version "1.19.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.19.0.tgz#1af5bf630409734a067cae29318aac7fa29a267c" @@ -6570,6 +6641,11 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +runnel@~0.5.1: + version "0.5.3" + resolved "https://registry.yarnpkg.com/runnel/-/runnel-0.5.3.tgz#f9362b165a05fc6f5e46e458f77a1f7ecdc0daec" + integrity sha512-XAVCMr+hCRGKA4AJdNit1aQC0EKCuCZnlxqfeh9u2CbSPSPyLSI/BfavMfoC/WUd6HyaRBWW1usNsVAqWN9hgw== + safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -6688,6 +6764,11 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +sigmund@~1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sigmund/-/sigmund-1.0.1.tgz#3ff21f198cad2175f9f3b781853fd94d0d19b590" + integrity sha512-fCvEXfh6NWpm+YSuY2bpXb/VIihqWA6hLsgboC+0nl71Q7N7o2eaCW8mJa/NLvQhs6jpd3VZV4UiUQlV6+lc8g== + signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" @@ -6858,6 +6939,11 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" +string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + integrity sha512-ev2QzSzWPYmy9GuqfIVildA4OdcGLeFZQrq5ys6RtiuF+RQQiZWr8TZNyAcuVXyQRYfEO+MsoB/1BuQVhOJuoQ== + string_decoder@~1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" @@ -7001,6 +7087,14 @@ through2@^2.0.0: readable-stream "~2.3.6" xtend "~4.0.1" +through2@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.2.3.tgz#eb3284da4ea311b6cc8ace3653748a52abf25a3f" + integrity sha512-mLa8Bn2mZurjyomGKWRu3Bo2mvoQojFks9NvOK8H+k4kDJNkdEqG522KFZsEFBEl6rKkxTgFbE5+OPcgfvPEHA== + dependencies: + readable-stream "~1.1.9" + xtend "~2.1.1" + "through@>=2.2.7 <3": version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" @@ -7437,6 +7531,16 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +viralify@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/viralify/-/viralify-0.4.2.tgz#e50e2ab8c7b445389c1d99d754e4436234992070" + integrity sha512-GRQFXKRDvFukIS96xQqJKuzhMSa320DK3VGf4gvCJh10tEv0aWGlo7GABq6euPpXVS0NBghiIRXwk8mc3LRipg== + dependencies: + ansicolors "~0.3.2" + glob "~3.2.7" + minimist "0.0.5" + runnel "~0.5.1" + vm-browserify@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-1.1.2.tgz#78641c488b8e6ca91a75f511e7a3b32a86e5dda0" @@ -7668,6 +7772,13 @@ xtend@^4.0.0, xtend@^4.0.1, xtend@^4.0.2, xtend@~4.0.1: resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + integrity sha512-vMNKzr2rHP9Dp/e1NQFnLQlwlhp9L/LfvnsVdHxN1f+uggyVI3i08uD14GPvCToPkdsRfyPqIyYGmIk58V98ZQ== + dependencies: + object-keys "~0.4.0" + y18n@^5.0.5: version "5.0.8" resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" From c894d09d8c6009752c6072637e916f2146da86d5 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Fri, 3 Mar 2023 08:30:28 -0500 Subject: [PATCH 18/24] Room call is an underride, not an override. (#3185) --- spec/unit/pushprocessor.spec.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/spec/unit/pushprocessor.spec.ts b/spec/unit/pushprocessor.spec.ts index 6fb02b18155..e1d12a2171a 100644 --- a/spec/unit/pushprocessor.spec.ts +++ b/spec/unit/pushprocessor.spec.ts @@ -180,11 +180,11 @@ describe("NotificationService", function () { enabled: true, rule_id: ".m.rule.room_one_to_one", }, - msc3914RoomCallRule, ], room: [], sender: [], underride: [ + msc3914RoomCallRule, { actions: ["dont-notify"], conditions: [ @@ -569,7 +569,7 @@ describe("NotificationService", function () { it("returns push rule when it is found in rule set", () => { expect(pushProcessor.getPushRuleAndKindById(".org.matrix.msc3914.rule.room.call")).toEqual({ - kind: "override", + kind: "underride", rule: msc3914RoomCallRule, }); }); From a82e22b5de2fb0d15ea966a076984d6c327d60b3 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Fri, 3 Mar 2023 13:30:38 +0000 Subject: [PATCH 19/24] Remove items incorrectly included in changelog for 23.4.0 (#3190) --- CHANGELOG.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8837d475fa7..e3964e35124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,8 +7,6 @@ Changes in [23.4.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23 * Polls: count undecryptable poll relations ([\#3163](https://github.com/matrix-org/matrix-js-sdk/pull/3163)). Contributed by @kerryarchibald. ## 🐛 Bug Fixes - * Fix spec compliance issue around encrypted `m.relates_to` ([\#3178](https://github.com/matrix-org/matrix-js-sdk/pull/3178)). - * Fix reactions in threads sometimes causing stuck notifications ([\#3146](https://github.com/matrix-org/matrix-js-sdk/pull/3146)). Fixes vector-im/element-web#24000. Contributed by @justjanne. * Better type guard parseTopicContent ([\#3165](https://github.com/matrix-org/matrix-js-sdk/pull/3165)). Fixes matrix-org/element-web-rageshakes#20177 and matrix-org/element-web-rageshakes#20178. * Fix a bug where events in encrypted rooms would sometimes erroneously increment the total unread counter after being processed locally. ([\#3130](https://github.com/matrix-org/matrix-js-sdk/pull/3130)). Fixes vector-im/element-web#24448. Contributed by @Half-Shot. * Stop the ICE disconnected timer on call terminate ([\#3147](https://github.com/matrix-org/matrix-js-sdk/pull/3147)). From b4cdc5a92397c92c551b91c695c16b2c9ca74727 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Mon, 6 Mar 2023 09:52:43 -0500 Subject: [PATCH 20/24] Implement MSC3758: a push rule condition to match event properties exactly (#3179) * Add some comments. * Support MSC3758 to exactly match values in push rule conditions. * Update to stable prefix. --- spec/unit/pushprocessor.spec.ts | 75 ++++++++++++++++++++++++++++++++- src/@types/PushRules.ts | 9 ++++ src/pushprocessor.ts | 36 ++++++++++++++-- 3 files changed, 116 insertions(+), 4 deletions(-) diff --git a/spec/unit/pushprocessor.spec.ts b/spec/unit/pushprocessor.spec.ts index e1d12a2171a..27b79f869a4 100644 --- a/spec/unit/pushprocessor.spec.ts +++ b/spec/unit/pushprocessor.spec.ts @@ -1,6 +1,6 @@ import * as utils from "../test-utils/test-utils"; import { IActionsObject, PushProcessor } from "../../src/pushprocessor"; -import { ConditionKind, EventType, IContent, MatrixClient, MatrixEvent } from "../../src"; +import { ConditionKind, EventType, IContent, MatrixClient, MatrixEvent, PushRuleActionName } from "../../src"; describe("NotificationService", function () { const testUserId = "@ali:matrix.org"; @@ -507,6 +507,79 @@ describe("NotificationService", function () { }); }); + describe("Test exact event matching", () => { + it.each([ + // Simple string matching. + { value: "bar", eventValue: "bar", expected: true }, + // Matches are case-sensitive. + { value: "bar", eventValue: "BAR", expected: false }, + // Matches must match the full string. + { value: "bar", eventValue: "barbar", expected: false }, + // Values should not be type-coerced. + { value: "bar", eventValue: true, expected: false }, + { value: "bar", eventValue: 1, expected: false }, + { value: "bar", eventValue: false, expected: false }, + // Boolean matching. + { value: true, eventValue: true, expected: true }, + { value: false, eventValue: false, expected: true }, + // Types should not be coerced. + { value: true, eventValue: "true", expected: false }, + { value: true, eventValue: 1, expected: false }, + { value: false, eventValue: null, expected: false }, + // Null matching. + { value: null, eventValue: null, expected: true }, + // Types should not be coerced + { value: null, eventValue: false, expected: false }, + { value: null, eventValue: 0, expected: false }, + { value: null, eventValue: "", expected: false }, + { value: null, eventValue: undefined, expected: false }, + // Compound values should never be matched. + { value: "bar", eventValue: ["bar"], expected: false }, + { value: "bar", eventValue: { bar: true }, expected: false }, + { value: true, eventValue: [true], expected: false }, + { value: true, eventValue: { true: true }, expected: false }, + { value: null, eventValue: [], expected: false }, + { value: null, eventValue: {}, expected: false }, + ])("test $value against $eventValue", ({ value, eventValue, expected }) => { + matrixClient.pushRules! = { + global: { + override: [ + { + actions: [PushRuleActionName.Notify], + conditions: [ + { + kind: ConditionKind.EventPropertyIs, + key: "content.foo", + value: value, + }, + ], + default: true, + enabled: true, + rule_id: ".m.rule.test", + }, + ], + }, + }; + + testEvent = utils.mkEvent({ + type: "m.room.message", + room: testRoomId, + user: "@alfred:localhost", + event: true, + content: { + foo: eventValue, + }, + }); + + const actions = pushProcessor.actionsForEvent(testEvent); + if (expected) { + expect(actions?.notify).toBeTruthy(); + } else { + expect(actions?.notify).toBeFalsy(); + } + }); + }); + it.each([ // The properly escaped key works. { key: "content.m\\.test.foo", pattern: "bar", expected: true }, diff --git a/src/@types/PushRules.ts b/src/@types/PushRules.ts index ab581f3680c..8f6d24a5b8c 100644 --- a/src/@types/PushRules.ts +++ b/src/@types/PushRules.ts @@ -62,6 +62,7 @@ export function isDmMemberCountCondition(condition: AnyMemberCountCondition): bo export enum ConditionKind { EventMatch = "event_match", + EventPropertyIs = "event_property_is", ContainsDisplayName = "contains_display_name", RoomMemberCount = "room_member_count", SenderNotificationPermission = "sender_notification_permission", @@ -77,9 +78,16 @@ export interface IPushRuleCondition { export interface IEventMatchCondition extends IPushRuleCondition { key: string; pattern?: string; + // Note that value property is an optimization for patterns which do not do + // any globbing and when the key is not "content.body". value?: string; } +export interface IEventPropertyIsCondition extends IPushRuleCondition { + key: string; + value: string | boolean | null | number; +} + export interface IContainsDisplayNameCondition extends IPushRuleCondition { // no additional fields } @@ -105,6 +113,7 @@ export interface ICallStartedPrefixCondition extends IPushRuleCondition> unfortunately does not resolve this at the time of writing. export type PushRuleCondition = | IEventMatchCondition + | IEventPropertyIsCondition | IContainsDisplayNameCondition | IRoomMemberCountCondition | ISenderNotificationPermissionCondition diff --git a/src/pushprocessor.ts b/src/pushprocessor.ts index 76f18d90081..614fa3375f7 100644 --- a/src/pushprocessor.ts +++ b/src/pushprocessor.ts @@ -25,6 +25,7 @@ import { ICallStartedPrefixCondition, IContainsDisplayNameCondition, IEventMatchCondition, + IEventPropertyIsCondition, IPushRule, IPushRules, IRoomMemberCountCondition, @@ -337,6 +338,8 @@ export class PushProcessor { switch (cond.kind) { case ConditionKind.EventMatch: return this.eventFulfillsEventMatchCondition(cond, ev); + case ConditionKind.EventPropertyIs: + return this.eventFulfillsEventPropertyIsCondition(cond, ev); case ConditionKind.ContainsDisplayName: return this.eventFulfillsDisplayNameCondition(cond, ev); case ConditionKind.RoomMemberCount: @@ -435,6 +438,13 @@ export class PushProcessor { return content.body.search(pat) > -1; } + /** + * Check whether the given event matches the push rule condition by fetching + * the property from the event and comparing against the condition's glob-based + * pattern. + * @param cond - The push rule condition to check for a match. + * @param ev - The event to check for a match. + */ private eventFulfillsEventMatchCondition(cond: IEventMatchCondition, ev: MatrixEvent): boolean { if (!cond.key) { return false; @@ -445,6 +455,9 @@ export class PushProcessor { return false; } + // XXX This does not match in a case-insensitive manner. + // + // See https://spec.matrix.org/v1.5/client-server-api/#conditions-1 if (cond.value) { return cond.value === val; } @@ -461,6 +474,20 @@ export class PushProcessor { return !!val.match(regex); } + /** + * Check whether the given event matches the push rule condition by fetching + * the property from the event and comparing exactly against the condition's + * value. + * @param cond - The push rule condition to check for a match. + * @param ev - The event to check for a match. + */ + private eventFulfillsEventPropertyIsCondition(cond: IEventPropertyIsCondition, ev: MatrixEvent): boolean { + if (!cond.key || cond.value === undefined) { + return false; + } + return cond.value === this.valueForDottedKey(cond.key, ev); + } + private eventFulfillsCallStartedCondition( _cond: ICallStartedCondition | ICallStartedPrefixCondition, ev: MatrixEvent, @@ -578,10 +605,13 @@ export class PushProcessor { } for (; currentIndex < parts.length; ++currentIndex) { - const thisPart = parts[currentIndex]; - if (isNullOrUndefined(val[thisPart])) { - return null; + // The previous iteration resulted in null or undefined, bail (and + // avoid the type error of attempting to retrieve a property). + if (isNullOrUndefined(val)) { + return undefined; } + + const thisPart = parts[currentIndex]; val = val[thisPart]; } return val; From e119dc4e89426cf1ea111a7836c98d7e543d1732 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 7 Mar 2023 11:19:22 +0000 Subject: [PATCH 21/24] Prepare changelog for v23.5.0-rc.1 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e3964e35124..5b018489f95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +Changes in [23.5.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23.5.0-rc.1) (2023-03-07) +============================================================================================================ + +## ✨ Features + * Implement MSC3758: a push rule condition to match event properties exactly ([\#3179](https://github.com/matrix-org/matrix-js-sdk/pull/3179)). + * Enable group calls without video and audio track by configuration of MatrixClient ([\#3162](https://github.com/matrix-org/matrix-js-sdk/pull/3162)). Contributed by @EnricoSchw. + * Updates to protocol used for Sign in with QR code ([\#3155](https://github.com/matrix-org/matrix-js-sdk/pull/3155)). Contributed by @hughns. + * Implement MSC3873 to handle escaped dots in push rule keys ([\#3134](https://github.com/matrix-org/matrix-js-sdk/pull/3134)). Fixes undefined/matrix-js-sdk#1454. + +## 🐛 Bug Fixes + * Fix spec compliance issue around encrypted `m.relates_to` ([\#3178](https://github.com/matrix-org/matrix-js-sdk/pull/3178)). + * Fix reactions in threads sometimes causing stuck notifications ([\#3146](https://github.com/matrix-org/matrix-js-sdk/pull/3146)). Fixes vector-im/element-web#24000. Contributed by @justjanne. + Changes in [23.4.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23.4.0) (2023-02-28) ================================================================================================== From 13d95c82199c9ee9072634187bd3b0530d706135 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 7 Mar 2023 11:19:25 +0000 Subject: [PATCH 22/24] v23.5.0-rc.1 --- package.json | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 1a7b58490e7..4fdc1105c49 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "23.4.0", + "version": "23.5.0-rc.1", "description": "Matrix Client-Server SDK for Javascript", "engines": { "node": ">=16.0.0" @@ -32,8 +32,8 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.ts", - "browser": "./src/browser-index.ts", + "main": "./lib/index.js", + "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.ts", "matrix_lib_main": "./lib/index.js", @@ -168,5 +168,6 @@ "no-rust-crypto": { "src/rust-crypto/index.ts$": "./src/rust-crypto/browserify-index.ts" } - } + }, + "typings": "./lib/index.d.ts" } From 0cfc67c6797e96d2e026325585049d9991d99658 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 15 Mar 2023 12:39:38 +0000 Subject: [PATCH 23/24] Prepare changelog for v23.5.0 --- CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b018489f95..fb28276cec2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,5 @@ -Changes in [23.5.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23.5.0-rc.1) (2023-03-07) -============================================================================================================ +Changes in [23.5.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v23.5.0) (2023-03-15) +================================================================================================== ## ✨ Features * Implement MSC3758: a push rule condition to match event properties exactly ([\#3179](https://github.com/matrix-org/matrix-js-sdk/pull/3179)). From 26663e67fd8fd1810c68e0c354b2ac2bf711067d Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Wed, 15 Mar 2023 12:39:41 +0000 Subject: [PATCH 24/24] v23.5.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4fdc1105c49..151458b5a19 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "23.5.0-rc.1", + "version": "23.5.0", "description": "Matrix Client-Server SDK for Javascript", "engines": { "node": ">=16.0.0"