From 41bf8c2d5f4a2e9d345d7e4d564f48144b3f3d3b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 8 Feb 2022 19:17:28 +0000 Subject: [PATCH 01/26] Yarn upgrade (#2164) --- yarn.lock | 359 +++++++++++++++++++++++++++++------------------------- 1 file changed, 192 insertions(+), 167 deletions(-) diff --git a/yarn.lock b/yarn.lock index 72f92af25f1..86876acc576 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,10 +26,17 @@ dependencies: tunnel "0.0.6" +"@ampproject/remapping@^2.0.0": + version "2.1.0" + resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.1.0.tgz#72becdf17ee44b2d1ac5651fb12f1952c336fe23" + integrity sha512-d5RysTlJ7hmw5Tw4UxgxcY3lkMe92n8sXCcuLPAyIAHK6j8DefDwtGnVVDgOnv+RnEosulDJ9NPKQL27bDId0g== + dependencies: + "@jridgewell/trace-mapping" "^0.3.0" + "@babel/cli@^7.12.10": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.16.8.tgz#44b9be7706762bfa3bff8adbf746da336eb0ab7c" - integrity sha512-FTKBbxyk5TclXOGmwYyqelqP5IF6hMxaeJskd85jbR5jBfYlwqgwAbJwnixi1ZBbTqKfFuAA95mdmUFeSRwyJA== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/cli/-/cli-7.17.0.tgz#9b932d8f08a2e218fcdd9bba456044eb0a2e0b2c" + integrity sha512-es10YH/ejXbg551vtnmEzIPe3MQRNOS644o3pf8vUr1tIeNzVNlP8BBvs1Eh7roh5A+k2fEHUas+ZptOWHA1fQ== dependencies: commander "^4.0.1" convert-source-map "^1.1.0" @@ -50,35 +57,35 @@ "@babel/highlight" "^7.16.7" "@babel/compat-data@^7.13.11", "@babel/compat-data@^7.16.4", "@babel/compat-data@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.16.8.tgz#31560f9f29fdf1868de8cb55049538a1b9732a60" - integrity sha512-m7OkX0IdKLKPpBlJtF561YJal5y/jyI5fNfWbPxh2D/nbzzGI4qRyrD8xO2jB24u7l+5I2a43scCG2IrfjC50Q== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.17.0.tgz#86850b8597ea6962089770952075dcaabb8dba34" + integrity sha512-392byTlpGWXMv4FbyWw3sAZ/FrW/DrwqLGXpy0mbyNe9Taqv1mg9yON5/o0cnr8XYCkFTZbC1eV+c+LAROgrng== "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.7.5": - version "7.16.12" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.12.tgz#5edc53c1b71e54881315923ae2aedea2522bb784" - integrity sha512-dK5PtG1uiN2ikk++5OzSYsitZKny4wOCD0nrO4TqnW4BVBTQ2NGS3NgilvT/TEyxTST7LNyWV/T4tXDoD3fOgg== + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.17.2.tgz#2c77fc430e95139d816d39b113b31bf40fb22337" + integrity sha512-R3VH5G42VSDolRHyUO4V2cfag8WHcZyxdq5Z/m8Xyb92lW/Erm/6kM+XtRFGf3Mulre3mveni2NHfEUws8wSvw== dependencies: + "@ampproject/remapping" "^2.0.0" "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" + "@babel/generator" "^7.17.0" "@babel/helper-compilation-targets" "^7.16.7" "@babel/helper-module-transforms" "^7.16.7" - "@babel/helpers" "^7.16.7" - "@babel/parser" "^7.16.12" + "@babel/helpers" "^7.17.2" + "@babel/parser" "^7.17.0" "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.10" - "@babel/types" "^7.16.8" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.2" json5 "^2.1.2" semver "^6.3.0" - source-map "^0.5.0" "@babel/eslint-parser@^7.12.10": - version "7.16.5" - resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.16.5.tgz#48d3485091d6e36915358e4c0d0b2ebe6da90462" - integrity sha512-mUqYa46lgWqHKQ33Q6LNCGp/wPR3eqOYTUixHFsfrSQqRxH0+WOzca75iEjFr5RDGH1dDz622LaHhLOzOuQRUA== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/eslint-parser/-/eslint-parser-7.17.0.tgz#eabb24ad9f0afa80e5849f8240d0e5facc2d90d6" + integrity sha512-PUEJ7ZBXbRkbq3qqM/jZ2nIuakUBqCYc7Qf52Lj7dlZ6zERnqisdHioL0l4wwQZnmskMeasqUNzLBFKs3nylXA== dependencies: eslint-scope "^5.1.1" eslint-visitor-keys "^2.1.0" @@ -91,12 +98,12 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.11", "@babel/generator@^7.16.8": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.8.tgz#359d44d966b8cd059d543250ce79596f792f2ebe" - integrity sha512-1ojZwE9+lOXzcWdWmO6TbUzDfqLD39CmEhN8+2cX9XkDo5yW1OpgfejfliysR2AWLpMamTiOiAp/mtroaymhpw== +"@babel/generator@^7.12.11", "@babel/generator@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.17.0.tgz#7bd890ba706cd86d3e2f727322346ffdbf98f65e" + integrity sha512-I3Omiv6FGOC29dtlZhkfXO6pgkmukJSlT26QjVvS1DGZe/NzSVCPG41X0tS21oZkJYlovfj9qDWgKP+Cn4bXxw== dependencies: - "@babel/types" "^7.16.8" + "@babel/types" "^7.17.0" jsesc "^2.5.1" source-map "^0.5.0" @@ -126,9 +133,9 @@ semver "^6.3.0" "@babel/helper-create-class-features-plugin@^7.16.10", "@babel/helper-create-class-features-plugin@^7.16.7": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.16.10.tgz#8a6959b9cc818a88815ba3c5474619e9c0f2c21c" - integrity sha512-wDeej0pu3WN/ffTxMNCPW5UCiOav8IcLRxSIyp/9+IF2xJUM9h/OYjg0IJLHaL6F8oU8kqMz9nc1vryXhMsgXg== + version "7.17.1" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.17.1.tgz#9699f14a88833a7e055ce57dcd3ffdcd25186b21" + integrity sha512-JBdSr/LtyYIno/pNnJ75lBcqc3Z1XXujzPanHqjvvrhOA+DTceTFuJi8XjmWTZh4r3fsdfqaCMN0iZemdkxZHQ== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" "@babel/helper-environment-visitor" "^7.16.7" @@ -139,12 +146,12 @@ "@babel/helper-split-export-declaration" "^7.16.7" "@babel/helper-create-regexp-features-plugin@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.16.7.tgz#0cb82b9bac358eb73bfbd73985a776bfa6b14d48" - integrity sha512-fk5A6ymfp+O5+p2yCkXAu5Kyj6v0xh0RBeNcAkYUMDvvAAoxvSKXn+Jb37t/yWFiQVDFK1ELpUTD8/aLhCPu+g== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.17.0.tgz#1dcc7d40ba0c6b6b25618997c5dbfd310f186fe1" + integrity sha512-awO2So99wG6KnlE+TPs6rn83gCz5WlEePJDTnLEqbchMVrBeAujURVphRdigsk094VhvZehFoNOihSlcBjwsXA== dependencies: "@babel/helper-annotate-as-pure" "^7.16.7" - regexpu-core "^4.7.1" + regexpu-core "^5.0.1" "@babel/helper-define-polyfill-provider@^0.3.1": version "0.3.1" @@ -298,14 +305,14 @@ "@babel/traverse" "^7.16.8" "@babel/types" "^7.16.8" -"@babel/helpers@^7.16.7": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.16.7.tgz#7e3504d708d50344112767c3542fc5e357fffefc" - integrity sha512-9ZDoqtfY7AuEOt3cxchfii6C7GDyyMBffktR5B2jvWv8u2+efwvpnVKXMWzNehqy68tKgAfSwfdw/lWpthS2bw== +"@babel/helpers@^7.17.2": + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.17.2.tgz#23f0a0746c8e287773ccd27c14be428891f63417" + integrity sha512-0Qu7RLR1dILozr/6M0xgj+DFPmi6Bnulgm9M8BVa9ZCWxDqlSnqt3cf8IDPB5m45sVXUZ0kuQAgUrdSFFH79fQ== dependencies: "@babel/template" "^7.16.7" - "@babel/traverse" "^7.16.7" - "@babel/types" "^7.16.7" + "@babel/traverse" "^7.17.0" + "@babel/types" "^7.17.0" "@babel/highlight@^7.16.7": version "7.16.10" @@ -316,10 +323,10 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.10", "@babel/parser@^7.16.12", "@babel/parser@^7.16.7", "@babel/parser@^7.2.3", "@babel/parser@^7.9.4": - version "7.16.12" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.12.tgz#9474794f9a650cf5e2f892444227f98e28cdf8b6" - integrity sha512-VfaV15po8RiZssrkPweyvbGVSe4x2y+aciFCgn0n0/SJMR22cwofRV1mtnJQYcSB1wUTaA/X1LnA3es66MCO5A== +"@babel/parser@^7.1.0", "@babel/parser@^7.14.7", "@babel/parser@^7.16.7", "@babel/parser@^7.17.0", "@babel/parser@^7.2.3", "@babel/parser@^7.9.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.17.0.tgz#f0ac33eddbe214e4105363bb17c3341c5ffcc43c" + integrity sha512-VKXSCQx5D8S04ej+Dqsr1CzYvvWgf20jIw2D+YhQCrIlr2UZGaDds23Y0xg75/skOxpLCRpUZvk/1EAVkGoDOw== "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.7": version "7.16.7" @@ -784,9 +791,9 @@ "@babel/helper-plugin-utils" "^7.16.7" "@babel/plugin-transform-runtime@^7.12.10": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.16.10.tgz#53d9fd3496daedce1dd99639097fa5d14f4c7c2c" - integrity sha512-9nwTiqETv2G7xI4RvXHNfpGdr8pAA+Q/YtN3yLK7OoK7n9OibVm/xymJ838a9A6E/IciOLPj82lZk0fW6O4O7w== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.17.0.tgz#0a2e08b5e2b2d95c4b1d3b3371a2180617455b70" + integrity sha512-fr7zPWnKXNc1xoHfrIU9mN/4XKX4VLZ45Q+oMhfsYIaHvg7mHgmhfOy/ckRWqDK7XF3QDigRpkh5DKq6+clE8A== dependencies: "@babel/helper-module-imports" "^7.16.7" "@babel/helper-plugin-utils" "^7.16.7" @@ -956,20 +963,20 @@ "@babel/plugin-transform-typescript" "^7.16.7" "@babel/register@^7.12.10": - version "7.16.9" - resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.16.9.tgz#fcfb23cfdd9ad95c9771e58183de83b513857806" - integrity sha512-jJ72wcghdRIlENfvALcyODhNoGE5j75cYHdC+aQMh6cU/P86tiiXTp9XYZct1UxUMo/4+BgQRyNZEGx0KWGS+g== + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/register/-/register-7.17.0.tgz#8051e0b7cb71385be4909324f072599723a1f084" + integrity sha512-UNZsMAZ7uKoGHo1HlEXfteEOYssf64n/PNLHGqOKq/bgYcu/4LrQWAHJwSCb3BRZK8Hi5gkJdRcwrGTO2wtRCg== dependencies: clone-deep "^4.0.1" find-cache-dir "^2.0.0" make-dir "^2.1.0" - pirates "^4.0.0" + pirates "^4.0.5" source-map-support "^0.5.16" "@babel/runtime@^7.12.5", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4": - version "7.16.7" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.7.tgz#03ff99f64106588c9c403c6ecb8c3bafbbdff1fa" - integrity sha512-9E9FJowqAsytyOY6LG+1KuueckRL+aQW+mKvXRXnuFGyRAyepJPmEo9vgMfXUA6O9u3IeEdv9MAkppFcaQwogQ== + version "7.17.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.17.2.tgz#66f68591605e59da47523c631416b18508779941" + integrity sha512-hzeyJyMA1YGdJTuWU0e/j4wKXrU4OMFvY2MSlaI9B7VQb0r5cxTE3EAIS2Q7Tn2RIcDkRvTA/v2JsAEhxe99uw== dependencies: regenerator-runtime "^0.13.4" @@ -982,26 +989,26 @@ "@babel/parser" "^7.16.7" "@babel/types" "^7.16.7" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.10", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8": - version "7.16.10" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.10.tgz#448f940defbe95b5a8029975b051f75993e8239f" - integrity sha512-yzuaYXoRJBGMlBhsMJoUW7G1UmSb/eXr/JHYM/MsOJgavJibLwASijW7oXBdw3NQ6T0bW7Ty5P/VarOs9cHmqw== +"@babel/traverse@^7.1.0", "@babel/traverse@^7.1.6", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.7", "@babel/traverse@^7.16.8", "@babel/traverse@^7.17.0": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.17.0.tgz#3143e5066796408ccc880a33ecd3184f3e75cd30" + integrity sha512-fpFIXvqD6kC7c7PUNnZ0Z8cQXlarCLtCUpt2S1Dx7PjoRtCFffvOkHHSom+m5HIxMZn5bIBVb71lhabcmjEsqg== dependencies: "@babel/code-frame" "^7.16.7" - "@babel/generator" "^7.16.8" + "@babel/generator" "^7.17.0" "@babel/helper-environment-visitor" "^7.16.7" "@babel/helper-function-name" "^7.16.7" "@babel/helper-hoist-variables" "^7.16.7" "@babel/helper-split-export-declaration" "^7.16.7" - "@babel/parser" "^7.16.10" - "@babel/types" "^7.16.8" + "@babel/parser" "^7.17.0" + "@babel/types" "^7.17.0" debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": - version "7.16.8" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.8.tgz#0ba5da91dd71e0a4e7781a30f22770831062e3c1" - integrity sha512-smN2DQc5s4M7fntyjGtyIPbRJv6wW4rU/94fmYJ7PKQuZkC0qGMHXJbg6sNGt12JmVr4k5YaptI/XtiLJBnmIg== +"@babel/types@^7.0.0", "@babel/types@^7.16.0", "@babel/types@^7.16.7", "@babel/types@^7.16.8", "@babel/types@^7.17.0", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": + version "7.17.0" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.17.0.tgz#a826e368bccb6b3d84acd76acad5c0d87342390b" + integrity sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw== dependencies: "@babel/helper-validator-identifier" "^7.16.7" to-fast-properties "^2.0.0" @@ -1222,6 +1229,24 @@ "@types/yargs" "^15.0.0" chalk "^4.0.0" +"@jridgewell/resolve-uri@^3.0.3": + version "3.0.4" + resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.0.4.tgz#b876e3feefb9c8d3aa84014da28b5e52a0640d72" + integrity sha512-cz8HFjOFfUBtvN+NXYSFMHYRdxZMaEl0XypVrhzxBgadKIXhIkRd8aMeHhmF56Sl7SuS8OnUpQ73/k9LE4VnLg== + +"@jridgewell/sourcemap-codec@^1.4.10": + version "1.4.10" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.10.tgz#baf57b4e2a690d4f38560171f91783656b7f8186" + integrity sha512-Ht8wIW5v165atIX1p+JvKR5ONzUyF4Ac8DZIQ5kZs9zrb6M8SJNXpx1zn04rn65VjBMygRoMXcyYwNK0fT7bEg== + +"@jridgewell/trace-mapping@^0.3.0": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.2.tgz#e051581782a770c30ba219634f2019241c5d3cde" + integrity sha512-9KzzH4kMjA2XmBRHfqG2/Vtl7s92l6uNDd0wW7frDE+EUvQFGqNXhWp0UGJjSkt3v2AYjzOZn1QO9XaTNJIt1Q== + dependencies: + "@jridgewell/resolve-uri" "^3.0.3" + "@jridgewell/sourcemap-codec" "^1.4.10" + "@matrix-org/olm@https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz": version "3.2.8" resolved "https://gitlab.matrix.org/api/v4/projects/27/packages/npm/@matrix-org/olm/-/@matrix-org/olm-3.2.8.tgz#8d53636d045e1776e2a2ec6613e57330dd9ce856" @@ -1497,14 +1522,14 @@ integrity sha512-eC4U9MlIcu2q0KQmXszyn5Akca/0jrQmwDRgpAMJai7qBWq4amIQhZyNau4VYGtCeALvW1/NtjzJJ567aZxfKA== "@types/node@*": - version "17.0.13" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.13.tgz#5ed7ed7c662948335fcad6c412bb42d99ea754e3" - integrity sha512-Y86MAxASe25hNzlDbsviXl8jQHb0RDvKt4c40ZJQ1Don0AAL0STLZSs4N+6gLEO55pedy7r2cLwS+ZDxPm/2Bw== + version "17.0.16" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.16.tgz#e3733f46797b9df9e853ca9f719c8a6f7b84cd26" + integrity sha512-ydLaGVfQOQ6hI1xK2A5nVh8bl0OGoIfYMxPWHqqYe9bTkWCfqiVvZoh2I/QF2sNSkZzZyROBoTefIEI+PB6iIA== "@types/node@12": - version "12.20.42" - resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.42.tgz#2f021733232c2130c26f9eabbdd3bfd881774733" - integrity sha512-aI3/oo5DzyiI5R/xAhxxRzfZlWlsbbqdgxfTPkqu/Zt+23GXiJvMCyPJT4+xKSXOnLqoL8jJYMLTwvK2M3a5hw== + version "12.20.43" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.43.tgz#6cf47894da4a4748c62fccf720ba269e1b1ff5a4" + integrity sha512-HCfJdaYqJX3BCzeihgZrD7b85Cu05OC/GVJ4kEYIflwUs4jbnUlLLWoq7hw1LBcdvUyehO+gr6P5JQ895/2ZfA== "@types/normalize-package-data@^2.4.0": version "2.4.1" @@ -1554,13 +1579,13 @@ "@types/yargs-parser" "*" "@typescript-eslint/eslint-plugin@^5.6.0": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.10.1.tgz#870195d0f2146b36d11fc71131b75aba52354c69" - integrity sha512-xN3CYqFlyE/qOcy978/L0xLR2HlcAGIyIK5sMOasxaaAPfQRj/MmMV6OC3I7NZO84oEUdWCOju34Z9W8E0pFDQ== + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.11.0.tgz#3b866371d8d75c70f9b81535e7f7d3aa26527c7a" + integrity sha512-HJh33bgzXe6jGRocOj4FmefD7hRY4itgjzOrSs3JPrTNXsX7j5+nQPciAUj/1nZtwo2kAc3C75jZO+T23gzSGw== dependencies: - "@typescript-eslint/scope-manager" "5.10.1" - "@typescript-eslint/type-utils" "5.10.1" - "@typescript-eslint/utils" "5.10.1" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/type-utils" "5.11.0" + "@typescript-eslint/utils" "5.11.0" debug "^4.3.2" functional-red-black-tree "^1.0.1" ignore "^5.1.8" @@ -1569,68 +1594,68 @@ tsutils "^3.21.0" "@typescript-eslint/parser@^5.6.0": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.10.1.tgz#4ce9633cc33fc70bc13786cb793c1a76fe5ad6bd" - integrity sha512-GReo3tjNBwR5RnRO0K2wDIDN31cM3MmDtgyQ85oAxAmC5K3j/g85IjP+cDfcqDsDDBf1HNKQAD0WqOYL8jXqUA== + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-5.11.0.tgz#b4fcaf65513f9b34bdcbffdda055724a5efb7e04" + integrity sha512-x0DCjetHZYBRovJdr3U0zG9OOdNXUaFLJ82ehr1AlkArljJuwEsgnud+Q7umlGDFLFrs8tU8ybQDFocp/eX8mQ== dependencies: - "@typescript-eslint/scope-manager" "5.10.1" - "@typescript-eslint/types" "5.10.1" - "@typescript-eslint/typescript-estree" "5.10.1" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/typescript-estree" "5.11.0" debug "^4.3.2" -"@typescript-eslint/scope-manager@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.10.1.tgz#f0539c73804d2423506db2475352a4dec36cd809" - integrity sha512-Lyvi559Gvpn94k7+ElXNMEnXu/iundV5uFmCUNnftbFrUbAJ1WBoaGgkbOBm07jVZa682oaBU37ao/NGGX4ZDg== +"@typescript-eslint/scope-manager@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-5.11.0.tgz#f5aef83ff253f457ecbee5f46f762298f0101e4b" + integrity sha512-z+K4LlahDFVMww20t/0zcA7gq/NgOawaLuxgqGRVKS0PiZlCTIUtX0EJbC0BK1JtR4CelmkPK67zuCgpdlF4EA== dependencies: - "@typescript-eslint/types" "5.10.1" - "@typescript-eslint/visitor-keys" "5.10.1" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/visitor-keys" "5.11.0" -"@typescript-eslint/type-utils@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.10.1.tgz#5e526c00142585e40ab1503e83f1ff608c367405" - integrity sha512-AfVJkV8uck/UIoDqhu+ptEdBoQATON9GXnhOpPLzkQRJcSChkvD//qsz9JVffl2goxX+ybs5klvacE9vmrQyCw== +"@typescript-eslint/type-utils@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-5.11.0.tgz#58be0ba73d1f6ef8983d79f7f0bc2209b253fefe" + integrity sha512-wDqdsYO6ofLaD4DsGZ0jGwxp4HrzD2YKulpEZXmgN3xo4BHJwf7kq49JTRpV0Gx6bxkSUmc9s0EIK1xPbFFpIA== dependencies: - "@typescript-eslint/utils" "5.10.1" + "@typescript-eslint/utils" "5.11.0" debug "^4.3.2" tsutils "^3.21.0" -"@typescript-eslint/types@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.10.1.tgz#dca9bd4cb8c067fc85304a31f38ec4766ba2d1ea" - integrity sha512-ZvxQ2QMy49bIIBpTqFiOenucqUyjTQ0WNLhBM6X1fh1NNlYAC6Kxsx8bRTY3jdYsYg44a0Z/uEgQkohbR0H87Q== +"@typescript-eslint/types@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-5.11.0.tgz#ba345818a2540fdf2755c804dc2158517ab61188" + integrity sha512-cxgBFGSRCoBEhvSVLkKw39+kMzUKHlJGVwwMbPcTZX3qEhuXhrjwaZXWMxVfxDgyMm+b5Q5b29Llo2yow8Y7xQ== -"@typescript-eslint/typescript-estree@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.10.1.tgz#b268e67be0553f8790ba3fe87113282977adda15" - integrity sha512-PwIGnH7jIueXv4opcwEbVGDATjGPO1dx9RkUl5LlHDSe+FXxPwFL5W/qYd5/NHr7f6lo/vvTrAzd0KlQtRusJQ== +"@typescript-eslint/typescript-estree@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-5.11.0.tgz#53f9e09b88368191e52020af77c312a4777ffa43" + integrity sha512-yVH9hKIv3ZN3lw8m/Jy5I4oXO4ZBMqijcXCdA4mY8ull6TPTAoQnKKrcZ0HDXg7Bsl0Unwwx7jcXMuNZc0m4lg== dependencies: - "@typescript-eslint/types" "5.10.1" - "@typescript-eslint/visitor-keys" "5.10.1" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/visitor-keys" "5.11.0" debug "^4.3.2" globby "^11.0.4" is-glob "^4.0.3" semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/utils@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.10.1.tgz#fa682a33af47080ba2c4368ee0ad2128213a1196" - integrity sha512-RRmlITiUbLuTRtn/gcPRi4202niF+q7ylFLCKu4c+O/PcpRvZ/nAUwQ2G00bZgpWkhrNLNnvhZLbDn8Ml0qsQw== +"@typescript-eslint/utils@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-5.11.0.tgz#d91548ef180d74c95d417950336d9260fdbe1dc5" + integrity sha512-g2I480tFE1iYRDyMhxPAtLQ9HAn0jjBtipgTCZmd9I9s11OV8CTsG+YfFciuNDcHqm4csbAgC2aVZCHzLxMSUw== dependencies: "@types/json-schema" "^7.0.9" - "@typescript-eslint/scope-manager" "5.10.1" - "@typescript-eslint/types" "5.10.1" - "@typescript-eslint/typescript-estree" "5.10.1" + "@typescript-eslint/scope-manager" "5.11.0" + "@typescript-eslint/types" "5.11.0" + "@typescript-eslint/typescript-estree" "5.11.0" eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/visitor-keys@5.10.1": - version "5.10.1" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.10.1.tgz#29102de692f59d7d34ecc457ed59ab5fc558010b" - integrity sha512-NjQ0Xinhy9IL979tpoTRuLKxMc0zJC7QVSdeerXs2/QvOy2yRkzX5dRb10X5woNUdJgU8G3nYRDlI33sq1K4YQ== +"@typescript-eslint/visitor-keys@5.11.0": + version "5.11.0" + resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-5.11.0.tgz#888542381f1a2ac745b06d110c83c0b261487ebb" + integrity sha512-E8w/vJReMGuloGxJDkpPlGwhxocxOpSVgSvjiLO5IxZPmxZF30weOeJYyPSEACwM+X4NziYS9q+WkN/2DHYQwA== dependencies: - "@typescript-eslint/types" "5.10.1" + "@typescript-eslint/types" "5.11.0" eslint-visitor-keys "^3.0.0" JSONStream@^1.0.3: @@ -1723,9 +1748,9 @@ ajv@^6.10.0, ajv@^6.12.3, ajv@^6.12.4: uri-js "^4.2.2" ajv@^8.0.1: - version "8.9.0" - resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.9.0.tgz#738019146638824dea25edcf299dcba1b0e7eb18" - integrity sha512-qOKJyNj/h+OWx7s5DePL6Zu1KeM9jPZhwBqs+7DzP6bGOvqzVCSf0xueYmVuaC/oQ/VtS2zLMLHdQFbkka+XDQ== + version "8.10.0" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-8.10.0.tgz#e573f719bd3af069017e3b66538ab968d040e54d" + integrity sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw== dependencies: fast-deep-equal "^3.1.1" json-schema-traverse "^1.0.0" @@ -2003,12 +2028,12 @@ babel-plugin-polyfill-corejs2@^0.3.0: semver "^6.1.1" babel-plugin-polyfill-corejs3@^0.5.0: - version "0.5.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.1.tgz#d66183bf10976ea677f4149a7fcc4d8df43d4060" - integrity sha512-TihqEe4sQcb/QcPJvxe94/9RZuLQuF1+To4WqQcRvc+3J3gLCPIPgDKzGLG6zmQLfH3nn25heRuDNkS2KR4I8A== + version "0.5.2" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz#aabe4b2fa04a6e038b688c5e55d44e78cd3a5f72" + integrity sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ== dependencies: "@babel/helper-define-polyfill-provider" "^0.3.1" - core-js-compat "^3.20.0" + core-js-compat "^3.21.0" babel-plugin-polyfill-regenerator@^0.3.0: version "0.3.1" @@ -2452,9 +2477,9 @@ camelcase@^6.0.0: integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== caniuse-lite@^1.0.30001286: - version "1.0.30001304" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001304.tgz#38af55ed3fc8220cb13e35e6e7309c8c65a05559" - integrity sha512-bdsfZd6K6ap87AGqSHJP/s1V+U6Z5lyrcbBu3ovbCCf8cSYpwTtGrCBObMpJqwxfTbLW6YTIdbb1jEeTelcpYQ== + version "1.0.30001309" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001309.tgz#e0ee78b9bec0704f67304b00ff3c5c0c768a9f62" + integrity sha512-Pl8vfigmBXXq+/yUz1jUwULeq9xhMJznzdc/xwl4WclDAuebcTHVefpz8lE/bMI+UN7TOkSSe7B7RnZd6+dzjA== capture-exit@^2.0.0: version "2.0.0" @@ -2745,10 +2770,10 @@ copy-descriptor@^0.1.0: resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40= -core-js-compat@^3.20.0, core-js-compat@^3.20.2: - version "3.20.3" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.20.3.tgz#d71f85f94eb5e4bea3407412e549daa083d23bd6" - integrity sha512-c8M5h0IkNZ+I92QhIpuSijOxGAcj3lgpsWdkCqmUTZNwidujF4r3pi6x1DCN+Vcs5qTS2XWWMfWSuCqyupX8gw== +core-js-compat@^3.20.2, core-js-compat@^3.21.0: + version "3.21.0" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.21.0.tgz#bcc86aa5a589cee358e7a7fa0a4979d5a76c3885" + integrity sha512-OSXseNPSK2OPJa6GdtkMz/XxeXx8/CJvfhQWTqd6neuUraujcL4jVsjkLQz1OWnax8xVQJnRPe0V2jqNWORA+A== dependencies: browserslist "^4.19.1" semver "7.0.0" @@ -3094,9 +3119,9 @@ ecc-jsbn@~0.1.1: safer-buffer "^2.1.0" electron-to-chromium@^1.4.17: - version "1.4.57" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.57.tgz#2b2766df76ac8dbc0a1d41249bc5684a31849892" - integrity sha512-FNC+P5K1n6pF+M0zIK+gFCoXcJhhzDViL3DRIGy2Fv5PohuSES1JHR7T+GlwxSxlzx4yYbsuzCZvHxcBSRCIOw== + version "1.4.66" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.66.tgz#d7453d363dcd7b06ed1757adcde34d724e27b367" + integrity sha512-f1RXFMsvwufWLwYUxTiP7HmjprKXrqEWHiQkjAYa9DJeVIlZk5v8gBGcaV+FhtXLly6C1OTVzQY+2UQrACiLlg== elliptic@^6.5.3: version "6.5.4" @@ -4640,9 +4665,9 @@ istanbul-lib-source-maps@^4.0.0: source-map "^0.6.1" istanbul-reports@^3.0.2: - version "3.1.3" - resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.3.tgz#4bcae3103b94518117930d51283690960b50d3c2" - integrity sha512-x9LtDVtfm/t1GFiLl3NffC7hz+I1ragvgX1P/Lg1NlIagifZDKUkuuaAxH/qpwj2IuEfD8G2Bs/UKp+sZ/pKkg== + version "3.1.4" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.1.4.tgz#1b6f068ecbc6c331040aab5741991273e609e40c" + integrity sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw== dependencies: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" @@ -5546,9 +5571,9 @@ minimalistic-crypto-utils@^1.0.1: integrity sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo= minimatch@^3.0.2, minimatch@^3.0.4: - version "3.0.4" - resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" - integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA== + version "3.0.5" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.5.tgz#4da8f1290ee0f0f8e83d60ca69f8f134068604a3" + integrity sha512-tUpxzX0VAzJHjLu0xUfFv1gwVp9ba3IOuRAVH2EGuRW8a5emA2FlACLqiT/lDVtS1W+TGNwqz3sWaNyLgDJWuw== dependencies: brace-expansion "^1.1.7" @@ -5705,9 +5730,9 @@ node-notifier@^8.0.0: which "^2.0.2" node-releases@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.1.tgz#3d1d395f204f1f2f29a54358b9fb678765ad2fc5" - integrity sha512-CqyzN6z7Q6aMeF/ktcMVTzhAHCEpf8SOarwpzpf8pNBY2k5/oM34UHldUwp8VKI7uxct2HxSRdJjBaZeESzcxA== + version "2.0.2" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01" + integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg== normalize-package-data@^2.5.0: version "2.5.0" @@ -6084,7 +6109,7 @@ pify@^4.0.1: resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== -pirates@^4.0.0, pirates@^4.0.1: +pirates@^4.0.1, pirates@^4.0.5: version "4.0.5" resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.5.tgz#feec352ea5c3268fb23a37c702ab1699f35a5f3b" integrity sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ== @@ -6492,10 +6517,10 @@ reflect.getprototypeof@^1.0.2: get-intrinsic "^1.1.1" which-builtin-type "^1.1.1" -regenerate-unicode-properties@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-9.0.0.tgz#54d09c7115e1f53dc2314a974b32c1c344efe326" - integrity sha512-3E12UeNSPfjrgwjkR81m5J7Aw/T55Tu7nUyZVQYCKEOs+2dkxEY+DpPtZzO4YruuiPb7NkYLVcyJC4+zCbk5pA== +regenerate-unicode-properties@^10.0.1: + version "10.0.1" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.0.1.tgz#7f442732aa7934a3740c779bb9b3340dccc1fb56" + integrity sha512-vn5DU6yg6h8hP/2OkQo3K7uVILvY4iu0oI4t3HFa81UPkhGJwkRwM10JEc3upjdhHjs/k8GJY1sRBhk5sr69Bw== dependencies: regenerate "^1.4.2" @@ -6534,27 +6559,27 @@ regexpp@^3.1.0, regexpp@^3.2.0: resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== -regexpu-core@^4.7.1: - version "4.8.0" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.8.0.tgz#e5605ba361b67b1718478501327502f4479a98f0" - integrity sha512-1F6bYsoYiz6is+oz70NWur2Vlh9KWtswuRuzJOfeYUrfPX2o8n74AnUVaOGDbUqVGO9fNHu48/pjJO4sNVwsOg== +regexpu-core@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-5.0.1.tgz#c531122a7840de743dcf9c83e923b5560323ced3" + integrity sha512-CriEZlrKK9VJw/xQGJpQM5rY88BtuL8DM+AEwvcThHilbxiTAy8vq4iJnd2tqq8wLmjbGZzP7ZcKFjbGkmEFrw== dependencies: regenerate "^1.4.2" - regenerate-unicode-properties "^9.0.0" - regjsgen "^0.5.2" - regjsparser "^0.7.0" + regenerate-unicode-properties "^10.0.1" + regjsgen "^0.6.0" + regjsparser "^0.8.2" unicode-match-property-ecmascript "^2.0.0" unicode-match-property-value-ecmascript "^2.0.0" -regjsgen@^0.5.2: - version "0.5.2" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" - integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== +regjsgen@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.6.0.tgz#83414c5354afd7d6627b16af5f10f41c4e71808d" + integrity sha512-ozE883Uigtqj3bx7OhL1KNbCzGyW2NQZPl6Hs09WTvCuZD5sTI4JY58bkbQWa/Y9hxIsvJ3M8Nbf7j54IqeZbA== -regjsparser@^0.7.0: - version "0.7.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.7.0.tgz#a6b667b54c885e18b52554cb4960ef71187e9968" - integrity sha512-A4pcaORqmNMDVwUjWoTzuhwMGpP+NykpfqAsEgI1FSH/EzC7lrN5TMd+kN8YCovX+jMpu8eaqXgXPCa0g8FQNQ== +regjsparser@^0.8.2: + version "0.8.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.8.4.tgz#8a14285ffcc5de78c5b95d62bbf413b6bc132d5f" + integrity sha512-J3LABycON/VNEu3abOviqGHuB/LOtOQj8SKmfP9anY5GfAVw/SPjwzSjxGjbZXIxbGfqTHtJw58C2Li/WkStmA== dependencies: jsesc "~0.5.0" @@ -6848,9 +6873,9 @@ side-channel@^1.0.4: object-inspect "^1.9.0" signal-exit@^3.0.0, signal-exit@^3.0.2: - version "3.0.6" - resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.6.tgz#24e630c4b0f03fea446a2bd299e62b4a6ca8d0af" - integrity sha512-sDl4qMFpijcGw22U5w63KmD3cZJfBuFlVNbVMKje2keoKML7X2UzWbc4XrmEbDwg0NXJc3yv4/ox7b+JWb57kQ== + version "3.0.7" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" + integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== simple-concat@^1.0.0: version "1.0.1" @@ -7483,9 +7508,9 @@ type@^1.0.1: integrity sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg== type@^2.5.0: - version "2.5.0" - resolved "https://registry.yarnpkg.com/type/-/type-2.5.0.tgz#0a2e78c2e77907b252abe5f298c1b01c63f0db3d" - integrity sha512-180WMDQaIMm3+7hGXWf12GtdniDEy7nYcyFMKJn/eZz/6tSLXrUN9V0wKSbMjej0I1WHWbpREDEKHtqPQa9NNw== + version "2.6.0" + resolved "https://registry.yarnpkg.com/type/-/type-2.6.0.tgz#3ca6099af5981d36ca86b78442973694278a219f" + integrity sha512-eiDBDOmkih5pMbo9OqsqPRGMljLodLcwd5XD5JbtNB0o89xZAwynY9EdCDsJU7LtcVCClu9DvM7/0Ep1hYX3EQ== typedarray-to-buffer@^3.1.5: version "3.1.5" @@ -7967,9 +7992,9 @@ write-file-atomic@^3.0.0: typedarray-to-buffer "^3.1.5" ws@^7.4.6: - version "7.5.6" - resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.6.tgz#e59fc509fb15ddfb65487ee9765c5a51dec5fe7b" - integrity sha512-6GLgCqo2cy2A2rjCNFlxQS6ZljG/coZfZXclldI8FB/1G3CCI36Zd8xy2HrFVACi8tfk5XrgLQEk+P0Tnz9UcA== + version "7.5.7" + resolved "https://registry.yarnpkg.com/ws/-/ws-7.5.7.tgz#9e0ac77ee50af70d58326ecff7e85eb3fa375e67" + integrity sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A== xml-name-validator@^3.0.0: version "3.0.0" From ea0eaff212a71d7accad471355a4c411b3935321 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Wed, 9 Feb 2022 08:36:43 -0500 Subject: [PATCH 02/26] Back up keys before logging out (#2158) --- src/client.ts | 12 +++++++++++- src/crypto/backup.ts | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/client.ts b/src/client.ts index acf9accd302..3ebc0740f98 100644 --- a/src/client.ts +++ b/src/client.ts @@ -6881,7 +6881,17 @@ export class MatrixClient extends EventEmitter { * @param {module:client.callback} callback Optional. * @return {Promise} Resolves: On success, the empty object */ - public logout(callback?: Callback): Promise<{}> { + public async logout(callback?: Callback): Promise<{}> { + if (this.crypto?.backupManager?.getKeyBackupEnabled()) { + try { + while (await this.crypto.backupManager.backupPendingKeys(200) > 0); + } catch (err) { + logger.error( + "Key backup request failed when logging out. Some keys may be missing from backup", + err, + ); + } + } return this.http.authedRequest( callback, Method.Post, '/logout', ); diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index 5c19d166ffb..a057de32db7 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -467,7 +467,7 @@ export class BackupManager { * @param {integer} limit Maximum number of keys to back up * @returns {integer} Number of sessions backed up */ - private async backupPendingKeys(limit: number): Promise { + public async backupPendingKeys(limit: number): Promise { const sessions = await this.baseApis.crypto.cryptoStore.getSessionsNeedingBackup(limit); if (!sessions.length) { return 0; From 47c5c4645e411c76ee1e3ecc66b4d2492f463ceb Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Thu, 10 Feb 2022 08:34:21 -0500 Subject: [PATCH 03/26] Check the backup info against the stored private key when determining trust. (#2167) --- src/crypto/backup.ts | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/src/crypto/backup.ts b/src/crypto/backup.ts index a057de32db7..3577fade720 100644 --- a/src/crypto/backup.ts +++ b/src/crypto/backup.ts @@ -313,11 +313,24 @@ export class BackupManager { return ret; } - const trustedPubkey = this.baseApis.crypto.sessionStore.getLocalTrustedBackupPubKey(); + const privKey = await this.baseApis.crypto.getSessionBackupPrivateKey(); + if (privKey) { + let algorithm; + try { + algorithm = await BackupManager.makeAlgorithm(backupInfo, async () => privKey); - if ("public_key" in backupInfo.auth_data && backupInfo.auth_data.public_key === trustedPubkey) { - logger.info("Backup public key " + trustedPubkey + " is trusted locally"); - ret.trusted_locally = true; + if (await algorithm.keyMatches(privKey)) { + logger.info("Backup is trusted locally"); + ret.trusted_locally = true; + } + } catch { + // do nothing -- if we have an error, then we don't mark it as + // locally trusted + } finally { + if (algorithm) { + algorithm.free(); + } + } } const mySigs = backupInfo.auth_data.signatures[this.baseApis.getUserId()] || {}; From 6b822ccd61f83362814b3da6a45acbe61b5f3bb0 Mon Sep 17 00:00:00 2001 From: Germain Date: Thu, 10 Feb 2022 15:09:46 +0000 Subject: [PATCH 04/26] Improve thread partitioning for 2nd degree relations (#2165) --- spec/integ/matrix-client-methods.spec.js | 167 ++++++----------------- src/@types/event.ts | 1 + src/client.ts | 99 +++++++++----- src/models/event-timeline-set.ts | 23 ++-- src/models/event.ts | 12 +- src/models/relations.ts | 8 +- src/models/room.ts | 65 ++++----- src/models/thread.ts | 43 +++--- src/sync.ts | 2 +- 9 files changed, 191 insertions(+), 229 deletions(-) diff --git a/spec/integ/matrix-client-methods.spec.js b/spec/integ/matrix-client-methods.spec.js index 3f793241d78..3c99e28625e 100644 --- a/spec/integ/matrix-client-methods.spec.js +++ b/spec/integ/matrix-client-methods.spec.js @@ -3,7 +3,6 @@ import { CRYPTO_ENABLED } from "../../src/client"; import { MatrixEvent } from "../../src/models/event"; import { Filter, MemoryStore, Room } from "../../src/matrix"; import { TestClient } from "../TestClient"; -import { Thread } from "../../src/models/thread"; describe("MatrixClient", function() { let client = null; @@ -405,6 +404,11 @@ describe("MatrixClient", function() { it("copies pre-thread in-timeline vote events onto both timelines", function() { client.clientOpts = { experimentalThreadSupport: true }; + + const eventMessageInThread = buildEventMessageInThread(); + const eventPollResponseReference = buildEventPollResponseReference(); + const eventPollStartThreadRoot = buildEventPollStartThreadRoot(); + const events = [ eventMessageInThread, eventPollResponseReference, @@ -435,6 +439,11 @@ describe("MatrixClient", function() { it("copies pre-thread in-timeline reactions onto both timelines", function() { client.clientOpts = { experimentalThreadSupport: true }; + + const eventMessageInThread = buildEventMessageInThread(); + const eventReaction = buildEventReaction(); + const eventPollStartThreadRoot = buildEventPollStartThreadRoot(); + const events = [ eventMessageInThread, eventReaction, @@ -456,6 +465,11 @@ describe("MatrixClient", function() { it("copies post-thread in-timeline vote events onto both timelines", function() { client.clientOpts = { experimentalThreadSupport: true }; + + const eventPollResponseReference = buildEventPollResponseReference(); + const eventMessageInThread = buildEventMessageInThread(); + const eventPollStartThreadRoot = buildEventPollStartThreadRoot(); + const events = [ eventPollResponseReference, eventMessageInThread, @@ -475,119 +489,13 @@ describe("MatrixClient", function() { ]); }); - it("copies post-thread in-thread vote events onto both timelines", function() { + it("copies post-thread in-timeline reactions onto both timelines", function() { client.clientOpts = { experimentalThreadSupport: true }; - // Events for this test only, because we hack around with them - const eventMessageInThread2 = new MatrixEvent({ - "age": 80098509, - "content": { - "algorithm": "m.megolm.v1.aes-sha2", - "ciphertext": "ENCRYPTEDSTUFF", - "device_id": "XISFUZSKHH", - "m.relates_to": { - "event_id": "$AAA2ojbPmxb6x8ECetn45hmND6cRDcjgv-j-to9m7Vo", - "m.in_reply_to": { - "event_id": "$AAA2ojbPmxb6x8ECetn45hmND6cRDcjgv-j-to9m7Vo", - }, - "rel_type": "io.element.thread", - }, - "sender_key": "i3N3CtG/CD2bGB8rA9fW6adLYSDvlUhf2iuU73L65Vg", - "session_id": "Ja11R/KG6ua0wdk8zAzognrxjio1Gm/RK2Gn6lFL804", - }, - "event_id": "$AAAhKIGYowtBblVLkRimeIg8TcdjETnxhDPGfi6NpDg", - "origin_server_ts": 1643815466378, - "room_id": "!STrMRsukXHtqQdSeHa:matrix.org", - "sender": "@andybalaam-test1:matrix.org", - "type": "m.room.encrypted", - "unsigned": { "age": 80098509 }, - "user_id": "@andybalaam-test1:matrix.org", - }); - - const eventPollStartThreadRoot2 = new MatrixEvent({ - "age": 80108647, - "content": { - "algorithm": "m.megolm.v1.aes-sha2", - "ciphertext": "ENCRYPTEDSTUFF", - "device_id": "XISFUZSKHH", - "sender_key": "i3N3CtG/CD2bGB8rA9fW6adLYSDvlUhf2iuU73L65Vg", - "session_id": "Ja11R/KG6ua0wdk8zAzognrxjio1Gm/RK2Gn6lFL804", - }, - "event_id": "$AAA2ojbPmxb6x8ECetn45hmND6cRDcjgv-j-to9m7Vo", - "origin_server_ts": 1643815456240, - "room_id": "!STrMRsukXHtqQdSeHa:matrix.org", - "sender": "@andybalaam-test1:matrix.org", - "type": "m.room.encrypted", - "unsigned": { "age": 80108647 }, - "user_id": "@andybalaam-test1:matrix.org", - }); - - const eventPollResponseReference2 = new MatrixEvent({ - "age": 80098509, - "content": { - "algorithm": "m.megolm.v1.aes-sha2", - "ciphertext": "ENCRYPTEDSTUFF", - "device_id": "XISFUZSKHH", - "m.relates_to": { - "event_id": "$AAA2ojbPmxb6x8ECetn45hmND6cRDcjgv-j-to9m7Vo", - "rel_type": "m.reference", - }, - "sender_key": "i3N3CtG/CD2bGB8rA9fW6adLYSDvlUhf2iuU73L65Vg", - "session_id": "Ja11R/KG6ua0wdk8zAzognrxjio1Gm/RK2Gn6lFL804", - }, - "event_id": "$AAAvpezvsF0cKgav3g8W-uEVS4WkDHgxbJZvL3uMR1g", - "origin_server_ts": 1643815458650, - "room_id": "!STrMRsukXHtqQdSeHa:matrix.org", - "sender": "@andybalaam-test1:matrix.org", - "type": "m.room.encrypted", - "unsigned": { "age": 80106237 }, - "user_id": "@andybalaam-test1:matrix.org", - }); - - // When we react within a thread, sometimes the thread root - // has isThreadRelation === true, because thread is set on it, - // but threadId is not. - eventPollStartThreadRoot2.setThread( - new Thread( - eventPollStartThreadRoot2, - { - client, - room: new Room(), - }, - ), - ); - - const events = [ - eventPollResponseReference2, - eventMessageInThread2, - eventPollStartThreadRoot2, - ]; - - const [timeline, threaded] = client.partitionThreadedEvents(events); - - expect(timeline).toEqual([ - eventPollResponseReference2, - // eventPollStartThreadRoot2, - // This is weird: by hacking the thread root to have an inconsistency - // between thread and threadId (which is what I have observed in the - // wild), we have persuaded the code that the thread root is actually - // within the thread, so it is not provided to the main timeline. - // - // This should go away when we fix this inconsistency. When that - // happens, we should probably delete this test. - ]); - - expect(threaded).toEqual([ - withThreadId( - eventPollResponseReference2, eventPollStartThreadRoot2.getId(), - ), - eventMessageInThread2, - eventPollStartThreadRoot2, // See note above for why this appears here. - ]); - }); + const eventReaction = buildEventReaction(); + const eventMessageInThread = buildEventMessageInThread(); + const eventPollStartThreadRoot = buildEventPollStartThreadRoot(); - it("copies post-thread in-timeline reactions onto both timelines", function() { - client.clientOpts = { experimentalThreadSupport: true }; const events = [ eventReaction, eventMessageInThread, @@ -610,6 +518,19 @@ describe("MatrixClient", function() { it("sends room state events to the main timeline only", function() { client.clientOpts = { experimentalThreadSupport: true }; // This is based on recording the events in a real room: + + const eventMessageInThread = buildEventMessageInThread(); + const eventPollResponseReference = buildEventPollResponseReference(); + const eventPollStartThreadRoot = buildEventPollStartThreadRoot(); + const eventRoomName = buildEventRoomName(); + const eventEncryption = buildEventEncryption(); + const eventGuestAccess = buildEventGuestAccess(); + const eventHistoryVisibility = buildEventHistoryVisibility(); + const eventJoinRules = buildEventJoinRules(); + const eventPowerLevels = buildEventPowerLevels(); + const eventMember = buildEventMember(); + const eventCreate = buildEventCreate(); + const events = [ eventMessageInThread, eventPollResponseReference, @@ -655,7 +576,7 @@ function withThreadId(event, newThreadId) { return ret; } -const eventMessageInThread = new MatrixEvent({ +const buildEventMessageInThread = () => new MatrixEvent({ "age": 80098509, "content": { "algorithm": "m.megolm.v1.aes-sha2", @@ -680,7 +601,7 @@ const eventMessageInThread = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventPollResponseReference = new MatrixEvent({ +const buildEventPollResponseReference = () => new MatrixEvent({ "age": 80098509, "content": { "algorithm": "m.megolm.v1.aes-sha2", @@ -702,7 +623,7 @@ const eventPollResponseReference = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventReaction = new MatrixEvent({ +const buildEventReaction = () => new MatrixEvent({ "content": { "m.relates_to": { "event_id": "$VLS2ojbPmxb6x8ECetn45hmND6cRDcjgv-j-to9m7Vo", @@ -721,7 +642,7 @@ const eventReaction = new MatrixEvent({ "room_id": "!STrMRsukXHtqQdSeHa:matrix.org", }); -const eventPollStartThreadRoot = new MatrixEvent({ +const buildEventPollStartThreadRoot = () => new MatrixEvent({ "age": 80108647, "content": { "algorithm": "m.megolm.v1.aes-sha2", @@ -739,7 +660,7 @@ const eventPollStartThreadRoot = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventRoomName = new MatrixEvent({ +const buildEventRoomName = () => new MatrixEvent({ "age": 80123249, "content": { "name": "1 poll, 1 vote, 1 thread", @@ -754,7 +675,7 @@ const eventRoomName = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventEncryption = new MatrixEvent({ +const buildEventEncryption = () => new MatrixEvent({ "age": 80123383, "content": { "algorithm": "m.megolm.v1.aes-sha2", @@ -769,7 +690,7 @@ const eventEncryption = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventGuestAccess = new MatrixEvent({ +const buildEventGuestAccess = () => new MatrixEvent({ "age": 80123473, "content": { "guest_access": "can_join", @@ -784,7 +705,7 @@ const eventGuestAccess = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventHistoryVisibility = new MatrixEvent({ +const buildEventHistoryVisibility = () => new MatrixEvent({ "age": 80123556, "content": { "history_visibility": "shared", @@ -799,7 +720,7 @@ const eventHistoryVisibility = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventJoinRules = new MatrixEvent({ +const buildEventJoinRules = () => new MatrixEvent({ "age": 80123696, "content": { "join_rule": "invite", @@ -814,7 +735,7 @@ const eventJoinRules = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventPowerLevels = new MatrixEvent({ +const buildEventPowerLevels = () => new MatrixEvent({ "age": 80124105, "content": { "ban": 50, @@ -849,7 +770,7 @@ const eventPowerLevels = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventMember = new MatrixEvent({ +const buildEventMember = () => new MatrixEvent({ "age": 80125279, "content": { "avatar_url": "mxc://matrix.org/aNtbVcFfwotudypZcHsIcPOc", @@ -866,7 +787,7 @@ const eventMember = new MatrixEvent({ "user_id": "@andybalaam-test1:matrix.org", }); -const eventCreate = new MatrixEvent({ +const buildEventCreate = () => new MatrixEvent({ "age": 80126105, "content": { "creator": "@andybalaam-test1:matrix.org", diff --git a/src/@types/event.ts b/src/@types/event.ts index 1d03e23c498..98c7de32f88 100644 --- a/src/@types/event.ts +++ b/src/@types/event.ts @@ -92,6 +92,7 @@ export enum EventType { export enum RelationType { Annotation = "m.annotation", Replace = "m.replace", + Reference = "m.reference", /** * Note, "io.element.thread" is hardcoded * Should be replaced with "m.thread" once MSC3440 lands diff --git a/src/client.ts b/src/client.ts index 3ebc0740f98..64d669b3dcf 100644 --- a/src/client.ts +++ b/src/client.ts @@ -3594,17 +3594,20 @@ export class MatrixClient extends EventEmitter { threadId = null; } - if (threadId && content["m.relates_to"]?.rel_type !== RelationType.Thread) { + // If we expect that an event is part of a thread but is missing the relation + // we need to add it manually, as well as the reply fallback + if (threadId && !content["m.relates_to"]?.rel_type) { content["m.relates_to"] = { ...content["m.relates_to"], "rel_type": RelationType.Thread, "event_id": threadId, }; - const thread = this.getRoom(roomId)?.threads.get(threadId); if (thread) { content["m.relates_to"]["m.in_reply_to"] = { - "event_id": thread.replyToEvent.getId(), + "event_id": thread.lastReply((ev: MatrixEvent) => { + return ev.isThreadRelation && !ev.status; + }), }; } } @@ -3652,6 +3655,7 @@ export class MatrixClient extends EventEmitter { const thread = room?.threads.get(threadId); if (thread) { localEvent.setThread(thread); + localEvent.setThreadId(thread.id); } // if this is a relation or redaction of an event @@ -9089,6 +9093,52 @@ export class MatrixClient extends EventEmitter { return threadRoots; } + private eventShouldLiveIn(event: MatrixEvent, room: Room, events: MatrixEvent[], roots: Set): { + shouldLiveInRoom: boolean; + shouldLiveInThread: boolean; + threadId?: string; + } { + // A thread relation is always only shown in a thread + if (event.isThreadRelation) { + return { + shouldLiveInRoom: false, + shouldLiveInThread: true, + threadId: event.relationEventId, + }; + } + + const parentEventId = event.getAssociatedId(); + const parentEvent = room?.findEventById(parentEventId) || events.find((mxEv: MatrixEvent) => ( + mxEv.getId() === parentEventId + )); + + // A reaction targetting the thread root needs to be routed to both the + // the main timeline and the associated thread + const targetingThreadRoot = parentEvent?.isThreadRoot || roots.has(event.relationEventId); + if (targetingThreadRoot) { + return { + shouldLiveInRoom: true, + shouldLiveInThread: true, + threadId: event.relationEventId, + }; + } + + // If the parent event also has an associated ID we want to re-run the + // computation for that parent event. + // In the case of the redaction of a reaction that targets a root event + // we want that redaction to be pushed to both timeline + if (parentEvent?.getAssociatedId()) { + return this.eventShouldLiveIn(parentEvent, room, events, roots); + } else { + // We've exhausted all scenarios, can safely assume that this event + // should live in the room timeline + return { + shouldLiveInRoom: true, + shouldLiveInThread: false, + }; + } + } + public partitionThreadedEvents(events: MatrixEvent[]): [MatrixEvent[], MatrixEvent[]] { // Indices to the events array, for readibility const ROOM = 0; @@ -9097,35 +9147,22 @@ export class MatrixClient extends EventEmitter { const threadRoots = this.findThreadRoots(events); return events.reduce((memo, event: MatrixEvent) => { const room = this.getRoom(event.getRoomId()); - // An event should live in the thread timeline if - // - It's a reply in thread event - // - It's related to a reply in thread event - let shouldLiveInThreadTimeline = event.isThreadRelation; - if (!shouldLiveInThreadTimeline) { - const parentEventId = event.parentEventId; - const parentEvent = room?.findEventById(parentEventId) || events.find((mxEv: MatrixEvent) => { - return mxEv.getId() === parentEventId; - }); - const targetingThreadRoot = parentEvent?.isThreadRoot || threadRoots.has(event.relationEventId); - - if (targetingThreadRoot && !event.isThreadRelation && event.relationEventId) { - // If we refer to the thread root, we should be copied - // into the thread as well as the main timeline. - // This happens for reactions, annotations, poll votes etc. - const copiedEvent = event.toSnapshot(); - - // The copied event is in this thread: - copiedEvent.setThreadId(parentEventId); - memo[THREAD].push(copiedEvent); - } else if (parentEvent?.isThreadRelation) { - // If our parent is in a thread, we are in that - // same thread too. (E.g. if I reply within a thread.) - shouldLiveInThreadTimeline = true; - event.setThreadId(parentEvent.threadRootId); - } + + const { + shouldLiveInRoom, + shouldLiveInThread, + threadId, + } = this.eventShouldLiveIn(event, room, events, threadRoots); + + if (shouldLiveInRoom) { + memo[ROOM].push(event); } - const targetTimeline = shouldLiveInThreadTimeline ? THREAD : ROOM; - memo[targetTimeline].push(event); + + if (shouldLiveInThread) { + event.setThreadId(threadId); + memo[THREAD].push(event); + } + return memo; }, [[], []]); } else { diff --git a/src/models/event-timeline-set.ts b/src/models/event-timeline-set.ts index b39cb80b28e..03408c08ba8 100644 --- a/src/models/event-timeline-set.ts +++ b/src/models/event-timeline-set.ts @@ -28,7 +28,6 @@ import { Room } from "./room"; import { Filter } from "../filter"; import { EventType, RelationType } from "../@types/event"; import { RoomState } from "./room-state"; -import { Thread } from "./thread"; // var DEBUG = false; const DEBUG = true; @@ -159,17 +158,12 @@ export class EventTimelineSet extends EventEmitter { * * @throws If opts.pendingEventOrdering was not 'detached' */ - public getPendingEvents(thread?: Thread): MatrixEvent[] { + public getPendingEvents(): MatrixEvent[] { if (!this.room || !this.displayPendingEvents) { return []; } - const pendingEvents = this.room.getPendingEvents(thread); - if (this.filter) { - return this.filter.filterRoomTimeline(pendingEvents); - } else { - return pendingEvents; - } + return this.room.getPendingEvents(); } /** * Get the live timeline for this room. @@ -756,7 +750,7 @@ export class EventTimelineSet extends EventEmitter { */ public getRelationsForEvent( eventId: string, - relationType: RelationType, + relationType: RelationType | string, eventType: EventType | string, ): Relations | undefined { if (!this.unstableClientRelationAggregation) { @@ -774,6 +768,17 @@ export class EventTimelineSet extends EventEmitter { return relationsWithRelType[eventType]; } + public getAllRelationsEventForEvent(eventId: string): MatrixEvent[] { + const relationsForEvent = this.relations[eventId] || {}; + const events = []; + for (const relationsRecord of Object.values(relationsForEvent)) { + for (const relations of Object.values(relationsRecord)) { + events.push(...relations.getRelations()); + } + } + return events; + } + /** * Set an event as the target event if any Relations exist for it already * diff --git a/src/models/event.ts b/src/models/event.ts index 14775805662..9b04ae0996c 100644 --- a/src/models/event.ts +++ b/src/models/event.ts @@ -512,8 +512,7 @@ export class MatrixEvent extends EventEmitter { if (relatesTo?.rel_type === RelationType.Thread) { return relatesTo.event_id; } else { - return this.threadId - || this.getThread()?.id; + return this.getThread()?.id || this.threadId; } } @@ -537,10 +536,6 @@ export class MatrixEvent extends EventEmitter { return !!threadDetails || (this.getThread()?.id === this.getId()); } - public get parentEventId(): string { - return this.replyEventId || this.relationEventId; - } - public get replyEventId(): string { // We're prefer ev.getContent() over ev.getWireContent() to make sure // we grab the latest edit with potentially new relations. But we also @@ -1427,7 +1422,9 @@ export class MatrixEvent extends EventEmitter { */ public getAssociatedId(): string | undefined { const relation = this.getRelation(); - if (relation) { + if (this.replyEventId) { + return this.replyEventId; + } else if (relation) { return relation.event_id; } else if (this.isRedaction()) { return this.event.redacts; @@ -1561,6 +1558,7 @@ export class MatrixEvent extends EventEmitter { */ public setThread(thread: Thread): void { this.thread = thread; + this.setThreadId(thread.id); this.reEmitter.reEmit(thread, [ThreadEvent.Ready, ThreadEvent.Update]); } diff --git a/src/models/relations.ts b/src/models/relations.ts index 2021b15a48f..29adaab6685 100644 --- a/src/models/relations.ts +++ b/src/models/relations.ts @@ -171,11 +171,11 @@ export class Relations extends EventEmitter { * @return {Array} * Relation events in insertion order. */ - public getRelations() { + public getRelations(): MatrixEvent[] { return [...this.relations]; } - private addAnnotationToAggregation(event: MatrixEvent) { + private addAnnotationToAggregation(event: MatrixEvent): void { const { key } = event.getRelation(); if (!key) { return; @@ -204,7 +204,7 @@ export class Relations extends EventEmitter { eventsFromSender.add(event); } - private removeAnnotationFromAggregation(event: MatrixEvent) { + private removeAnnotationFromAggregation(event: MatrixEvent): void { const { key } = event.getRelation(); if (!key) { return; @@ -240,7 +240,7 @@ export class Relations extends EventEmitter { * @param {MatrixEvent} redactedEvent * The original relation event that is about to be redacted. */ - private onBeforeRedaction = async (redactedEvent: MatrixEvent) => { + private onBeforeRedaction = async (redactedEvent: MatrixEvent): Promise => { if (!this.relations.has(redactedEvent)) { return; } diff --git a/src/models/room.ts b/src/models/room.ts index 9c59ae88b05..8132cc10ee5 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -512,16 +512,14 @@ export class Room extends EventEmitter { * * @throws If opts.pendingEventOrdering was not 'detached' */ - public getPendingEvents(thread?: Thread): MatrixEvent[] { + public getPendingEvents(): MatrixEvent[] { if (this.opts.pendingEventOrdering !== PendingEventOrdering.Detached) { throw new Error( "Cannot call getPendingEvents with pendingEventOrdering == " + this.opts.pendingEventOrdering); } - return this.pendingEventList.filter(event => { - return !thread || thread.id === event.threadRootId; - }); + return this.pendingEventList; } /** @@ -1358,7 +1356,7 @@ export class Room extends EventEmitter { } else if (event.isThreadRoot) { return this.threads.get(event.getId()); } else { - const parentEvent = this.findEventById(event.parentEventId); + const parentEvent = this.findEventById(event.getAssociatedId()); return this.findThreadForEvent(parentEvent); } } @@ -1396,21 +1394,15 @@ export class Room extends EventEmitter { } } - if (event.getUnsigned().transaction_id) { - const existingEvent = this.txnToEvent[event.getUnsigned().transaction_id]; - if (existingEvent) { - // remote echo of an event we sent earlier - this.handleRemoteEcho(event, existingEvent); - return; - } - } - this.emit(ThreadEvent.Update, thread); } - public createThread(rootEvent: MatrixEvent, events?: MatrixEvent[]): Thread | undefined { + public createThread(rootEvent: MatrixEvent, events: MatrixEvent[] = []): Thread | undefined { + const tl = this.getTimelineForEvent(rootEvent.getId()); + const relatedEvents = tl?.getTimelineSet().getAllRelationsEventForEvent(rootEvent.getId()) ?? []; + const thread = new Thread(rootEvent, { - initialEvents: events, + initialEvents: events.concat(relatedEvents), room: this, client: this.client, }); @@ -1564,8 +1556,7 @@ export class Room extends EventEmitter { EventTimeline.setEventMetadata(event, this.getLiveTimeline().getState(EventTimeline.FORWARDS), false); this.txnToEvent[txnId] = event; - const thread = this.findThreadForEvent(event); - if (this.opts.pendingEventOrdering === PendingEventOrdering.Detached && !thread) { + if (this.opts.pendingEventOrdering === PendingEventOrdering.Detached) { if (this.pendingEventList.some((e) => e.status === EventStatus.NOT_SENT)) { logger.warn("Setting event as NOT_SENT due to messages in the same state"); event.setStatus(EventStatus.NOT_SENT); @@ -1581,8 +1572,7 @@ export class Room extends EventEmitter { if (event.isRedaction()) { const redactId = event.event.redacts; - let redactedEvent = this.pendingEventList && - this.pendingEventList.find(e => e.getId() === redactId); + let redactedEvent = this.pendingEventList?.find(e => e.getId() === redactId); if (!redactedEvent) { redactedEvent = this.findEventById(redactId); } @@ -1592,20 +1582,16 @@ export class Room extends EventEmitter { } } } else { - if (thread) { - thread.addEvent(event, false); - } else { - for (let i = 0; i < this.timelineSets.length; i++) { - const timelineSet = this.timelineSets[i]; - if (timelineSet.getFilter()) { - if (timelineSet.getFilter().filterRoomTimeline([event]).length) { - timelineSet.addEventToTimeline(event, - timelineSet.getLiveTimeline(), false); - } - } else { + for (let i = 0; i < this.timelineSets.length; i++) { + const timelineSet = this.timelineSets[i]; + if (timelineSet.getFilter()) { + if (timelineSet.getFilter().filterRoomTimeline([event]).length) { timelineSet.addEventToTimeline(event, timelineSet.getLiveTimeline(), false); } + } else { + timelineSet.addEventToTimeline(event, + timelineSet.getLiveTimeline(), false); } } } @@ -1666,7 +1652,9 @@ export class Room extends EventEmitter { const thread = this.findThreadForEvent(event); if (thread) { thread.timelineSet.aggregateRelations(event); - } else { + } + + if (thread?.id === event.getAssociatedId() || !thread) { // TODO: We should consider whether this means it would be a better // design to lift the relations handling up to the room instead. for (let i = 0; i < this.timelineSets.length; i++) { @@ -1682,6 +1670,10 @@ export class Room extends EventEmitter { } } + public getEventForTxnId(txnId: string): MatrixEvent { + return this.txnToEvent[txnId]; + } + /** * Deal with the echo of a message we sent. * @@ -1696,7 +1688,7 @@ export class Room extends EventEmitter { * @fires module:client~MatrixClient#event:"Room.localEchoUpdated" * @private */ - private handleRemoteEcho(remoteEvent: MatrixEvent, localEvent: MatrixEvent): void { + public handleRemoteEcho(remoteEvent: MatrixEvent, localEvent: MatrixEvent): void { const oldEventId = localEvent.getId(); const newEventId = remoteEvent.getId(); const oldStatus = localEvent.status; @@ -1721,7 +1713,9 @@ export class Room extends EventEmitter { const thread = this.findThreadForEvent(remoteEvent); if (thread) { thread.timelineSet.handleRemoteEcho(localEvent, oldEventId, newEventId); - } else { + } + + if (thread?.id === remoteEvent.getAssociatedId() || !thread) { for (let i = 0; i < this.timelineSets.length; i++) { const timelineSet = this.timelineSets[i]; @@ -1791,7 +1785,8 @@ export class Room extends EventEmitter { const thread = this.findThreadForEvent(event); if (thread) { thread.timelineSet.replaceEventId(oldEventId, newEventId); - } else { + } + if (thread?.id === event.getAssociatedId() || !thread) { // if the event was already in the timeline (which will be the case if // opts.pendingEventOrdering==chronological), we need to update the // timeline map. diff --git a/src/models/thread.ts b/src/models/thread.ts index 8dbbc53f3fb..9465cc6a988 100644 --- a/src/models/thread.ts +++ b/src/models/thread.ts @@ -113,6 +113,27 @@ export class Thread extends TypedEventEmitter { return this.room.getLiveTimeline().getState(EventTimeline.FORWARDS); } + private addEventToTimeline(event: MatrixEvent, toStartOfTimeline: boolean): void { + if (event.getUnsigned().transaction_id) { + const existingEvent = this.room.getEventForTxnId(event.getUnsigned().transaction_id); + if (existingEvent) { + // remote echo of an event we sent earlier + this.room.handleRemoteEcho(event, existingEvent); + return; + } + } + + if (!this.findEventById(event.getId())) { + this.timelineSet.addEventToTimeline( + event, + this.liveTimeline, + toStartOfTimeline, + false, + this.roomState, + ); + } + } + /** * Add an event to the thread and updates * the tail/root references if needed @@ -123,36 +144,20 @@ export class Thread extends TypedEventEmitter { // Add all incoming events to the thread's timeline set when there's // no server support if (!this.hasServerSideSupport) { - if (this.timelineSet.findEventById(event.getId())) { - return; - } - // all the relevant membership info to hydrate events with a sender // is held in the main room timeline // We want to fetch the room state from there and pass it down to this thread // timeline set to let it reconcile an event with its relevant RoomMember event.setThread(this); - this.timelineSet.addEventToTimeline( - event, - this.liveTimeline, - toStartOfTimeline, - false, - this.roomState, - ); + this.addEventToTimeline(event, toStartOfTimeline); await this.client.decryptEventIfNeeded(event, {}); } if (this.hasServerSideSupport && this.initialEventsFetched) { - if (event.localTimestamp > this.lastReply().localTimestamp && !this.findEventById(event.getId())) { - this.timelineSet.addEventToTimeline( - event, - this.liveTimeline, - false, - false, - this.roomState, - ); + if (event.localTimestamp > this.lastReply().localTimestamp) { + this.addEventToTimeline(event, false); } } diff --git a/src/sync.ts b/src/sync.ts index 69ce748699b..c0da84c44d4 100644 --- a/src/sync.ts +++ b/src/sync.ts @@ -1727,7 +1727,7 @@ export class SyncApi { // extractRelatedEvents(event: MatrixEvent, events: MatrixEvent[], relatedEvents: MatrixEvent[] = []): MatrixEvent[] { // relatedEvents.push(event); - // const parentEventId = event.parentEventId; + // const parentEventId = event.getAssociatedId(); // const parentEventIndex = events.findIndex(event => event.getId() === parentEventId); // if (parentEventIndex > -1) { From d97c514b8da05a09c9e106162220b50042fd361a Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 10 Feb 2022 22:33:49 +0000 Subject: [PATCH 05/26] Log when member event membership is undefined (#2169) * Log when member event membership is undefined To diagnose https://github.com/vector-im/element-web/issues/20962 * May as well have a stack trace too --- src/models/room-member.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/models/room-member.ts b/src/models/room-member.ts index b0a2ba827d8..fab65ba8809 100644 --- a/src/models/room-member.ts +++ b/src/models/room-member.ts @@ -25,6 +25,7 @@ import * as utils from "../utils"; import { User } from "./user"; import { MatrixEvent } from "./event"; import { RoomState } from "./room-state"; +import { logger } from "../logger"; export class RoomMember extends EventEmitter { private _isOutOfBand = false; @@ -116,6 +117,15 @@ export class RoomMember extends EventEmitter { const oldMembership = this.membership; this.membership = event.getDirectionalContent().membership; + if (this.membership === undefined) { + // logging to diagnose https://github.com/vector-im/element-web/issues/20962 + // (logs event content, although only of membership events) + logger.trace( + `membership event with membership undefined (forwardLooking: ${event.forwardLooking})!`, + event.getContent(), + `prevcontent is `, event.getPrevContent(), + ); + } this.disambiguate = shouldDisambiguate( this.userId, From 25c115739cb767d55cae81eca2e7dbf3ce0d6883 Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Fri, 11 Feb 2022 11:16:10 +0000 Subject: [PATCH 06/26] Fix error in uploadContent() when file is empty under Node.js (#2155) * Fix error in uploadContent() when file is empty under Node.js * Make type safe check work * Make comment actually make sense --- src/http-api.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/http-api.ts b/src/http-api.ts index af3015ae26a..331fcb24821 100644 --- a/src/http-api.ts +++ b/src/http-api.ts @@ -437,10 +437,20 @@ export class MatrixHttpApi { queryParams.filename = fileName; } + const headers: Record = { "Content-Type": contentType }; + + // authedRequest uses `request` which is no longer maintained. + // `request` has a bug where if the body is zero bytes then you get an error: `Argument error, options.body`. + // See https://github.com/request/request/issues/920 + // if body looks like a byte array and empty then set the Content-Length explicitly as a workaround: + if ((body as unknown as ArrayLike).length === 0) { + headers["Content-Length"] = "0"; + } + promise = this.authedRequest( opts.callback, Method.Post, "/upload", queryParams, body, { prefix: "/_matrix/media/r0", - headers: { "Content-Type": contentType }, + headers, json: false, bodyParser, }, From d9c3b880fc8794a5072cd676c6f9f7ccf1ec9113 Mon Sep 17 00:00:00 2001 From: Germain Date: Fri, 11 Feb 2022 12:55:44 +0000 Subject: [PATCH 07/26] Revert event-mapper optimisations (#2171) --- src/event-mapper.ts | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/src/event-mapper.ts b/src/event-mapper.ts index 73d442039a8..9b938486021 100644 --- a/src/event-mapper.ts +++ b/src/event-mapper.ts @@ -29,21 +29,7 @@ export function eventMapperFor(client: MatrixClient, options: MapperOpts): Event const decrypt = options.decrypt !== false; function mapper(plainOldJsObject: Partial) { - const room = client.getRoom(plainOldJsObject.room_id); - let event: MatrixEvent; - - // If the event is already known to the room, let's re-use the model - // rather than creating a duplicate - if (room) { - event = room.findEventById(plainOldJsObject.event_id); - } - - // If no event is found or if the event found was only local we can - // safely create a new model - if (!event || event.status) { - event = new MatrixEvent(plainOldJsObject); - } - + const event = new MatrixEvent(plainOldJsObject); if (event.isEncrypted()) { if (!preventReEmit) { client.reEmitter.reEmit(event, [ From cfad8d361454244f2f153760e25fd49b59555483 Mon Sep 17 00:00:00 2001 From: Hubert Chathi Date: Fri, 11 Feb 2022 08:42:49 -0500 Subject: [PATCH 08/26] Enable key backup after we reset it (#2170) This ensures that we remember it if bootstrapCrossSigning gets called, so that the authData gets signed by the master key, if a new key is created. --- src/crypto/index.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index 03650d069ad..f9b77e3b402 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -953,6 +953,8 @@ export class Crypto extends EventEmitter { // sign with the device fingerprint await this.signObject(data.auth_data); + await this.backupManager.enableKeyBackup(data); + builder.addSessionBackup(data); } From 2fd08d72dc905e1159176d6fd3afe834261ac6e0 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 14 Feb 2022 15:17:32 +0000 Subject: [PATCH 09/26] Resetting package fields for development --- package.json | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index cb7711e34b4..0707a619de8 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "keywords": [ "matrix-org" ], - "main": "./lib/index.js", + "main": "./src/index.ts", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -115,6 +115,5 @@ "coverageReporters": [ "text" ] - }, - "typings": "./lib/index.d.ts" + } } From 2bb14698a50584a6cec26fa08ceecbeb77c8b14e Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 14 Feb 2022 19:11:06 +0000 Subject: [PATCH 10/26] Revert "Sign backup with cross-signing key when we reset it." (#2175) --- src/crypto/index.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/crypto/index.ts b/src/crypto/index.ts index f9b77e3b402..03650d069ad 100644 --- a/src/crypto/index.ts +++ b/src/crypto/index.ts @@ -953,8 +953,6 @@ export class Crypto extends EventEmitter { // sign with the device fingerprint await this.signObject(data.auth_data); - await this.backupManager.enableKeyBackup(data); - builder.addSessionBackup(data); } From 2910e62bb68db2e9bdf9eeb5b5d13d5bb269c424 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Tue, 15 Feb 2022 01:45:02 +0000 Subject: [PATCH 11/26] Fix synthetic read receipt handling (#2174) --- spec/unit/room.spec.js | 45 +++++++++++++++++++++++++++++++ src/models/room.ts | 60 +++++++++++++++++++++++++++++------------- 2 files changed, 87 insertions(+), 18 deletions(-) diff --git a/spec/unit/room.spec.js b/spec/unit/room.spec.js index 190bfdb5419..70b6a7a2e07 100644 --- a/spec/unit/room.spec.js +++ b/spec/unit/room.spec.js @@ -1143,6 +1143,51 @@ describe("Room", function() { ])); expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId()); }); + + it("should prioritise the most recent event even if it is synthetic", () => { + const events = [ + utils.mkMessage({ + room: roomId, user: userA, msg: "1111", + event: true, + }), + utils.mkMessage({ + room: roomId, user: userA, msg: "2222", + event: true, + }), + utils.mkMessage({ + room: roomId, user: userA, msg: "3333", + event: true, + }), + ]; + + room.addLiveEvents(events); + const ts = 13787898424; + + // check it initialises correctly + room.addReceipt(mkReceipt(roomId, [ + mkRecord(events[0].getId(), "m.read", userB, ts), + ])); + expect(room.getEventReadUpTo(userB)).toEqual(events[0].getId()); + + // 2>0, so it should move forward + room.addReceipt(mkReceipt(roomId, [ + mkRecord(events[2].getId(), "m.read", userB, ts), + ]), true); + expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId()); + expect(room.getReceiptsForEvent(events[2])).toEqual([ + { data: { ts }, type: "m.read", userId: userB }, + ]); + + // 1<2, so it should stay put + room.addReceipt(mkReceipt(roomId, [ + mkRecord(events[1].getId(), "m.read", userB, ts), + ])); + expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId()); + expect(room.getEventReadUpTo(userB, true)).toEqual(events[1].getId()); + expect(room.getReceiptsForEvent(events[2])).toEqual([ + { data: { ts }, type: "m.read", userId: userB }, + ]); + }); }); describe("getUsersReadUpTo", function() { diff --git a/src/models/room.ts b/src/models/room.ts index 8132cc10ee5..b9f79ba8804 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -108,6 +108,7 @@ interface IReceiptContent { const ReceiptPairRealIndex = 0; const ReceiptPairSyntheticIndex = 1; +// We will only hold a synthetic receipt if we do not have a real receipt or the synthetic is newer. type Receipts = { [receiptType: string]: { [userId: string]: [IWrappedReceipt, IWrappedReceipt]; // Pair (both nullable) @@ -1981,10 +1982,11 @@ export class Room extends EventEmitter { public getReadReceiptForUserId(userId: string, ignoreSynthesized = false): IWrappedReceipt | null { const [realReceipt, syntheticReceipt] = this.receipts["m.read"]?.[userId] ?? []; - if (ignoreSynthesized || realReceipt) { + if (ignoreSynthesized) { return realReceipt; } - return syntheticReceipt; + + return syntheticReceipt ?? realReceipt; } /** @@ -2048,10 +2050,10 @@ export class Room extends EventEmitter { /** * Add a receipt event to the room. * @param {MatrixEvent} event The m.receipt event. - * @param {Boolean} fake True if this event is implicit. + * @param {Boolean} synthetic True if this event is implicit. */ - public addReceipt(event: MatrixEvent, fake = false): void { - this.addReceiptsToStructure(event, fake); + public addReceipt(event: MatrixEvent, synthetic = false): void { + this.addReceiptsToStructure(event, synthetic); // send events after we've regenerated the structure & cache, otherwise things that // listened for the event would read stale data. this.emit("Room.receipt", event, this); @@ -2060,9 +2062,9 @@ export class Room extends EventEmitter { /** * Add a receipt event to the room. * @param {MatrixEvent} event The m.receipt event. - * @param {Boolean} fake True if this event is implicit. + * @param {Boolean} synthetic True if this event is implicit. */ - private addReceiptsToStructure(event: MatrixEvent, fake: boolean): void { + private addReceiptsToStructure(event: MatrixEvent, synthetic: boolean): void { const content = event.getContent(); Object.keys(content).forEach((eventId) => { Object.keys(content[eventId]).forEach((receiptType) => { @@ -2079,15 +2081,17 @@ export class Room extends EventEmitter { const pair = this.receipts[receiptType][userId]; let existingReceipt = pair[ReceiptPairRealIndex]; - if (fake && !existingReceipt) { - existingReceipt = pair[ReceiptPairSyntheticIndex]; + if (synthetic) { + existingReceipt = pair[ReceiptPairSyntheticIndex] ?? pair[ReceiptPairRealIndex]; } if (existingReceipt) { // we only want to add this receipt if we think it is later than the one we already have. // This is managed server-side, but because we synthesize RRs locally we have to do it here too. const ordering = this.getUnfilteredTimelineSet().compareEventOrdering( - existingReceipt.eventId, eventId); + existingReceipt.eventId, + eventId, + ); if (ordering !== null && ordering >= 0) { return; } @@ -2098,8 +2102,36 @@ export class Room extends EventEmitter { data: receipt, }; + const realReceipt = synthetic ? pair[ReceiptPairRealIndex] : wrappedReceipt; + const syntheticReceipt = synthetic ? wrappedReceipt : pair[ReceiptPairSyntheticIndex]; + + let ordering: number | null = null; + if (realReceipt && syntheticReceipt) { + ordering = this.getUnfilteredTimelineSet().compareEventOrdering( + realReceipt.eventId, + syntheticReceipt.eventId, + ); + } + + const preferSynthetic = ordering === null || ordering < 0; + // we don't bother caching just real receipts by event ID as there's nothing that would read it. + // Take the current cached receipt before we overwrite the pair elements. const cachedReceipt = pair[ReceiptPairSyntheticIndex] ?? pair[ReceiptPairRealIndex]; + + if (synthetic && preferSynthetic) { + pair[ReceiptPairSyntheticIndex] = wrappedReceipt; + } else if (!synthetic) { + pair[ReceiptPairRealIndex] = wrappedReceipt; + + if (!preferSynthetic) { + pair[ReceiptPairSyntheticIndex] = null; + } + } + + const newCachedReceipt = pair[ReceiptPairSyntheticIndex] ?? pair[ReceiptPairRealIndex]; + if (cachedReceipt === newCachedReceipt) return; + // clean up any previous cache entry if (cachedReceipt && this.receiptCacheByEventId[cachedReceipt.eventId]) { const previousEventId = cachedReceipt.eventId; @@ -2124,14 +2156,6 @@ export class Room extends EventEmitter { type: receiptType, data: receipt, }); - - if (fake) { - pair[ReceiptPairSyntheticIndex] = wrappedReceipt; - } else { - pair[ReceiptPairRealIndex] = wrappedReceipt; - // a real receipt for a receiptType+userId tuple should clobber any synthetic one - pair[ReceiptPairSyntheticIndex] = null; - } }); }); }); From e86d8861b9615e1a986633f8fad5f70991fffe50 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 15 Feb 2022 13:07:36 -0700 Subject: [PATCH 12/26] Add functions to support refresh tokens (#2178) * Add functions for refreshing access tokens * Add function to change the client's access token in flight * Appease the linter * Use sensible code style --- src/@types/auth.ts | 29 ++++++++++++++++++++++++++++ src/client.ts | 47 +++++++++++++++++++++++++++++++++++++--------- src/http-api.ts | 8 +++++++- 3 files changed, 74 insertions(+), 10 deletions(-) create mode 100644 src/@types/auth.ts diff --git a/src/@types/auth.ts b/src/@types/auth.ts new file mode 100644 index 00000000000..592974221ba --- /dev/null +++ b/src/@types/auth.ts @@ -0,0 +1,29 @@ +/* +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. +*/ + +// disable lint because these are wire responses +/* eslint-disable camelcase */ + +/** + * Represents a response to the CSAPI `/refresh` endpoint. + */ +export interface IRefreshTokenResponse { + access_token: string; + expires_in_ms: number; + refresh_token: string; +} + +/* eslint-enable camelcase */ diff --git a/src/client.ts b/src/client.ts index 64d669b3dcf..dafa4937f93 100644 --- a/src/client.ts +++ b/src/client.ts @@ -20,7 +20,7 @@ limitations under the License. */ import { EventEmitter } from "events"; -import { EmoteEvent, MessageEvent, NoticeEvent, IPartialEvent } from "matrix-events-sdk"; +import { EmoteEvent, IPartialEvent, MessageEvent, NoticeEvent } from "matrix-events-sdk"; import { ISyncStateData, SyncApi, SyncState } from "./sync"; import { EventStatus, IContent, IDecryptOptions, IEvent, MatrixEvent } from "./models/event"; @@ -52,6 +52,7 @@ import { PREFIX_MEDIA_R0, PREFIX_R0, PREFIX_UNSTABLE, + PREFIX_V1, retryNetworkOperation, UploadContentResponseType, } from "./http-api"; @@ -87,14 +88,7 @@ import { } from "./crypto/keybackup"; import { IIdentityServerProvider } from "./@types/IIdentityServerProvider"; import { MatrixScheduler } from "./scheduler"; -import { - IAuthData, - ICryptoCallbacks, - IMinimalEvent, - IRoomEvent, - IStateEvent, - NotificationCountType, -} from "./matrix"; +import { IAuthData, ICryptoCallbacks, IMinimalEvent, IRoomEvent, IStateEvent, NotificationCountType } from "./matrix"; import { CrossSigningKey, IAddSecretStorageKeyOpts, @@ -160,6 +154,7 @@ import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, Rule import { IThreepid } from "./@types/threepids"; import { CryptoStore } from "./crypto/store/base"; import { MediaHandler } from "./webrtc/mediaHandler"; +import { IRefreshTokenResponse } from "./@types/auth"; export type Store = IStore; export type SessionStore = WebStorageSessionStore; @@ -6619,6 +6614,14 @@ export class MatrixClient extends EventEmitter { return this.http.opts.accessToken || null; } + /** + * Set the access token associated with this account. + * @param {string} token The new access token. + */ + public setAccessToken(token: string) { + this.http.opts.accessToken = token; + } + /** * @return {boolean} true if there is a valid access_token for this client. */ @@ -6695,6 +6698,7 @@ export class MatrixClient extends EventEmitter { const params: any = { auth: auth, + refresh_token: true, // always ask for a refresh token - does nothing if unsupported }; if (username !== undefined && username !== null) { params.username = username; @@ -6772,6 +6776,31 @@ export class MatrixClient extends EventEmitter { return this.http.request(callback, Method.Post, "/register", params, data); } + /** + * Refreshes an access token using a provided refresh token. The refresh token + * must be valid for the current access token known to the client instance. + * + * Note that this function will not cause a logout if the token is deemed + * unknown by the server - the caller is responsible for managing logout + * actions on error. + * @param {string} refreshToken The refresh token. + * @return {Promise} Resolves to the new token. + * @return {module:http-api.MatrixError} Rejects with an error response. + */ + public refreshToken(refreshToken: string): Promise { + return this.http.authedRequest( + undefined, + Method.Post, + "/refresh", + undefined, + { refresh_token: refreshToken }, + { + prefix: PREFIX_V1, + inhibitLogoutEmit: true, // we don't want to cause logout loops + }, + ); + } + /** * @param {module:client.callback} callback Optional. * @return {Promise} Resolves: TODO diff --git a/src/http-api.ts b/src/http-api.ts index 331fcb24821..fd016c731e8 100644 --- a/src/http-api.ts +++ b/src/http-api.ts @@ -111,6 +111,12 @@ interface IRequestOpts { json?: boolean; // defaults to true qsStringifyOptions?: CoreOptions["qsStringifyOptions"]; bodyParser?(body: string): T; + + // Set to true to prevent the request function from emitting + // a Session.logged_out event. This is intended for use on + // endpoints where M_UNKNOWN_TOKEN is a valid/notable error + // response, such as with token refreshes. + inhibitLogoutEmit?: boolean; } export interface IUpload { @@ -596,7 +602,7 @@ export class MatrixHttpApi { const requestPromise = this.request(callback, method, path, queryParams, data, requestOpts); requestPromise.catch((err: MatrixError) => { - if (err.errcode == 'M_UNKNOWN_TOKEN') { + if (err.errcode == 'M_UNKNOWN_TOKEN' && !requestOpts?.inhibitLogoutEmit) { this.eventEmitter.emit("Session.logged_out", err); } else if (err.errcode == 'M_CONSENT_NOT_GIVEN') { this.eventEmitter.emit( From a3ddfd519be6b811458245787a40fd08be5c2304 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 17 Feb 2022 11:29:28 +0000 Subject: [PATCH 13/26] Fix synthetic read receipt handling (#2174) (#2183) Co-authored-by: Michael Telatynski <7t3chguy@gmail.com> --- spec/unit/room.spec.js | 45 +++++++++++++++++++++++++++++++ src/models/room.ts | 60 +++++++++++++++++++++++++++++------------- 2 files changed, 87 insertions(+), 18 deletions(-) diff --git a/spec/unit/room.spec.js b/spec/unit/room.spec.js index 190bfdb5419..70b6a7a2e07 100644 --- a/spec/unit/room.spec.js +++ b/spec/unit/room.spec.js @@ -1143,6 +1143,51 @@ describe("Room", function() { ])); expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId()); }); + + it("should prioritise the most recent event even if it is synthetic", () => { + const events = [ + utils.mkMessage({ + room: roomId, user: userA, msg: "1111", + event: true, + }), + utils.mkMessage({ + room: roomId, user: userA, msg: "2222", + event: true, + }), + utils.mkMessage({ + room: roomId, user: userA, msg: "3333", + event: true, + }), + ]; + + room.addLiveEvents(events); + const ts = 13787898424; + + // check it initialises correctly + room.addReceipt(mkReceipt(roomId, [ + mkRecord(events[0].getId(), "m.read", userB, ts), + ])); + expect(room.getEventReadUpTo(userB)).toEqual(events[0].getId()); + + // 2>0, so it should move forward + room.addReceipt(mkReceipt(roomId, [ + mkRecord(events[2].getId(), "m.read", userB, ts), + ]), true); + expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId()); + expect(room.getReceiptsForEvent(events[2])).toEqual([ + { data: { ts }, type: "m.read", userId: userB }, + ]); + + // 1<2, so it should stay put + room.addReceipt(mkReceipt(roomId, [ + mkRecord(events[1].getId(), "m.read", userB, ts), + ])); + expect(room.getEventReadUpTo(userB)).toEqual(events[2].getId()); + expect(room.getEventReadUpTo(userB, true)).toEqual(events[1].getId()); + expect(room.getReceiptsForEvent(events[2])).toEqual([ + { data: { ts }, type: "m.read", userId: userB }, + ]); + }); }); describe("getUsersReadUpTo", function() { diff --git a/src/models/room.ts b/src/models/room.ts index 9c59ae88b05..171a9ba01b2 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -108,6 +108,7 @@ interface IReceiptContent { const ReceiptPairRealIndex = 0; const ReceiptPairSyntheticIndex = 1; +// We will only hold a synthetic receipt if we do not have a real receipt or the synthetic is newer. type Receipts = { [receiptType: string]: { [userId: string]: [IWrappedReceipt, IWrappedReceipt]; // Pair (both nullable) @@ -1986,10 +1987,11 @@ export class Room extends EventEmitter { public getReadReceiptForUserId(userId: string, ignoreSynthesized = false): IWrappedReceipt | null { const [realReceipt, syntheticReceipt] = this.receipts["m.read"]?.[userId] ?? []; - if (ignoreSynthesized || realReceipt) { + if (ignoreSynthesized) { return realReceipt; } - return syntheticReceipt; + + return syntheticReceipt ?? realReceipt; } /** @@ -2053,10 +2055,10 @@ export class Room extends EventEmitter { /** * Add a receipt event to the room. * @param {MatrixEvent} event The m.receipt event. - * @param {Boolean} fake True if this event is implicit. + * @param {Boolean} synthetic True if this event is implicit. */ - public addReceipt(event: MatrixEvent, fake = false): void { - this.addReceiptsToStructure(event, fake); + public addReceipt(event: MatrixEvent, synthetic = false): void { + this.addReceiptsToStructure(event, synthetic); // send events after we've regenerated the structure & cache, otherwise things that // listened for the event would read stale data. this.emit("Room.receipt", event, this); @@ -2065,9 +2067,9 @@ export class Room extends EventEmitter { /** * Add a receipt event to the room. * @param {MatrixEvent} event The m.receipt event. - * @param {Boolean} fake True if this event is implicit. + * @param {Boolean} synthetic True if this event is implicit. */ - private addReceiptsToStructure(event: MatrixEvent, fake: boolean): void { + private addReceiptsToStructure(event: MatrixEvent, synthetic: boolean): void { const content = event.getContent(); Object.keys(content).forEach((eventId) => { Object.keys(content[eventId]).forEach((receiptType) => { @@ -2084,15 +2086,17 @@ export class Room extends EventEmitter { const pair = this.receipts[receiptType][userId]; let existingReceipt = pair[ReceiptPairRealIndex]; - if (fake && !existingReceipt) { - existingReceipt = pair[ReceiptPairSyntheticIndex]; + if (synthetic) { + existingReceipt = pair[ReceiptPairSyntheticIndex] ?? pair[ReceiptPairRealIndex]; } if (existingReceipt) { // we only want to add this receipt if we think it is later than the one we already have. // This is managed server-side, but because we synthesize RRs locally we have to do it here too. const ordering = this.getUnfilteredTimelineSet().compareEventOrdering( - existingReceipt.eventId, eventId); + existingReceipt.eventId, + eventId, + ); if (ordering !== null && ordering >= 0) { return; } @@ -2103,8 +2107,36 @@ export class Room extends EventEmitter { data: receipt, }; + const realReceipt = synthetic ? pair[ReceiptPairRealIndex] : wrappedReceipt; + const syntheticReceipt = synthetic ? wrappedReceipt : pair[ReceiptPairSyntheticIndex]; + + let ordering: number | null = null; + if (realReceipt && syntheticReceipt) { + ordering = this.getUnfilteredTimelineSet().compareEventOrdering( + realReceipt.eventId, + syntheticReceipt.eventId, + ); + } + + const preferSynthetic = ordering === null || ordering < 0; + // we don't bother caching just real receipts by event ID as there's nothing that would read it. + // Take the current cached receipt before we overwrite the pair elements. const cachedReceipt = pair[ReceiptPairSyntheticIndex] ?? pair[ReceiptPairRealIndex]; + + if (synthetic && preferSynthetic) { + pair[ReceiptPairSyntheticIndex] = wrappedReceipt; + } else if (!synthetic) { + pair[ReceiptPairRealIndex] = wrappedReceipt; + + if (!preferSynthetic) { + pair[ReceiptPairSyntheticIndex] = null; + } + } + + const newCachedReceipt = pair[ReceiptPairSyntheticIndex] ?? pair[ReceiptPairRealIndex]; + if (cachedReceipt === newCachedReceipt) return; + // clean up any previous cache entry if (cachedReceipt && this.receiptCacheByEventId[cachedReceipt.eventId]) { const previousEventId = cachedReceipt.eventId; @@ -2129,14 +2161,6 @@ export class Room extends EventEmitter { type: receiptType, data: receipt, }); - - if (fake) { - pair[ReceiptPairSyntheticIndex] = wrappedReceipt; - } else { - pair[ReceiptPairRealIndex] = wrappedReceipt; - // a real receipt for a receiptType+userId tuple should clobber any synthetic one - pair[ReceiptPairSyntheticIndex] = null; - } }); }); }); From 0db640a67959b3c46aa24b2975196959a59cbae6 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Thu, 17 Feb 2022 11:45:22 +0000 Subject: [PATCH 14/26] Prepare changelog for v15.5.2 --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6c732aa5335..ee22f17c2c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,9 @@ +Changes in [15.5.2](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v15.5.2) (2022-02-17) +================================================================================================== + +## 🐛 Bug Fixes + * Fix synthetic read receipt handling + Changes in [15.5.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v15.5.1) (2022-02-14) ================================================================================================== From 78dcae91438a9754320e76147da344c8923c9ea3 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Thu, 17 Feb 2022 11:45:23 +0000 Subject: [PATCH 15/26] v15.5.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cb7711e34b4..fc128081b9a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "15.5.1", + "version": "15.5.2", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", From 7a7318b636b732e6b9096466eef2491239a335c0 Mon Sep 17 00:00:00 2001 From: Patrick Cloke Date: Thu, 17 Feb 2022 12:39:17 -0500 Subject: [PATCH 16/26] Fix incorrect type referenced in receiptCacheByEventId. (#2185) --- src/models/room.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/models/room.ts b/src/models/room.ts index b9f79ba8804..135ffb9c05c 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -151,7 +151,7 @@ export class Room extends EventEmitter { // which pass in an event ID and get back some receipts, so we also store // a pre-cached list for this purpose. private receipts: Receipts = {}; // { receipt_type: { user_id: IReceipt } } - private receiptCacheByEventId: ReceiptCache = {}; // { event_id: IReceipt2[] } + private receiptCacheByEventId: ReceiptCache = {}; // { event_id: ICachedReceipt[] } private notificationCounts: Partial> = {}; private readonly timelineSets: EventTimelineSet[]; // any filtered timeline sets we're maintaining for this room From 4e72290d53808abdc7449029557ff2de64ac2f0b Mon Sep 17 00:00:00 2001 From: Germain Date: Mon, 21 Feb 2022 15:06:01 +0000 Subject: [PATCH 17/26] Null-guard for undefined rootEvent when creating a thread (#2187) --- src/models/room.ts | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/models/room.ts b/src/models/room.ts index 135ffb9c05c..e3cad8cb631 100644 --- a/src/models/room.ts +++ b/src/models/room.ts @@ -1398,12 +1398,17 @@ export class Room extends EventEmitter { this.emit(ThreadEvent.Update, thread); } - public createThread(rootEvent: MatrixEvent, events: MatrixEvent[] = []): Thread | undefined { - const tl = this.getTimelineForEvent(rootEvent.getId()); - const relatedEvents = tl?.getTimelineSet().getAllRelationsEventForEvent(rootEvent.getId()) ?? []; + public createThread(rootEvent: MatrixEvent | undefined, events: MatrixEvent[] = []): Thread | undefined { + if (rootEvent) { + const tl = this.getTimelineForEvent(rootEvent.getId()); + const relatedEvents = tl?.getTimelineSet().getAllRelationsEventForEvent(rootEvent.getId()); + if (relatedEvents) { + events = events.concat(relatedEvents); + } + } const thread = new Thread(rootEvent, { - initialEvents: events.concat(relatedEvents), + initialEvents: events, room: this, client: this.client, }); From a89c1990d6f2aff65cb2fc58b047fc2bb19fad3a Mon Sep 17 00:00:00 2001 From: Hugh Nimmo-Smith Date: Mon, 21 Feb 2022 15:45:43 +0000 Subject: [PATCH 18/26] Return send event response from MSC3089Branch.createNewVersion() (#2186) * Return send event response from MSC3089Branch.createNewVersion() * docs: update JSDoc to match --- src/models/MSC3089Branch.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/models/MSC3089Branch.ts b/src/models/MSC3089Branch.ts index 04046785957..0c2082a2a89 100644 --- a/src/models/MSC3089Branch.ts +++ b/src/models/MSC3089Branch.ts @@ -20,6 +20,7 @@ import { IContent, MatrixEvent } from "./event"; import { MSC3089TreeSpace } from "./MSC3089TreeSpace"; import { EventTimeline } from "./event-timeline"; import { FileType } from "../http-api"; +import type { ISendEventResponse } from ".."; /** * Represents a [MSC3089](https://github.com/matrix-org/matrix-doc/pull/3089) branch - a reference @@ -164,14 +165,14 @@ export class MSC3089Branch { * @param {File | String | Buffer | ReadStream | Blob} encryptedContents The encrypted contents. * @param {Partial} info The encrypted file information. * @param {IContent} additionalContent Optional event content fields to include in the message. - * @returns {Promise} Resolves when uploaded. + * @returns {Promise} Resolves to the file event's sent response. */ public async createNewVersion( name: string, encryptedContents: FileType, info: Partial, additionalContent?: IContent, - ): Promise { + ): Promise { const fileEventResponse = await this.directory.createFile(name, encryptedContents, info, { ...(additionalContent ?? {}), "m.new_content": true, @@ -193,6 +194,8 @@ export class MSC3089Branch { ...(this.indexEvent.getContent()), active: false, }, this.id); + + return fileEventResponse; } /** From 080426dfddb1744db3091bbc7de009bb70c8d32b Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 21 Feb 2022 17:11:14 +0000 Subject: [PATCH 19/26] Fix camera stuck on after call transfer (#2188) The 'Replaced' error code is handled specially (for better or worse) so was leaving the capture feeds open. Use the 'transfer' hangup reason which is what we should be using anyway (and were, on the line below for the other call...) --- src/webrtc/call.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webrtc/call.ts b/src/webrtc/call.ts index da4dc8a4b3e..e96928c0dd6 100644 --- a/src/webrtc/call.ts +++ b/src/webrtc/call.ts @@ -1943,7 +1943,7 @@ export class MatrixCall extends EventEmitter { await this.sendVoipEvent(EventType.CallReplaces, bodyToTransferee); - await this.terminate(CallParty.Local, CallErrorCode.Replaced, true); + await this.terminate(CallParty.Local, CallErrorCode.Transfered, true); await transferTargetCall.terminate(CallParty.Local, CallErrorCode.Transfered, true); } From 7b218905fbc35654a91213a8847809582c906a3e Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 21 Feb 2022 18:52:24 +0000 Subject: [PATCH 20/26] Fix bug where calls could break if rejected from somewhere else (#2189) * Fix bug where calls could ignore new events of rejected from somewhere else When callEventHandler passed a reject event to the call object, it assumed that always caused the call to end and deleted it from the list, so it never got any more events. The point of a reject is that it doesn't end the call if it's already been picked up though. This only removes the call if it's actually ended. * Use ts-expect-error --- src/webrtc/callEventHandler.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/webrtc/callEventHandler.ts b/src/webrtc/callEventHandler.ts index 7b7ca0f7149..6599971921e 100644 --- a/src/webrtc/callEventHandler.ts +++ b/src/webrtc/callEventHandler.ts @@ -257,7 +257,11 @@ export class CallEventHandler { } else { call.onRejectReceived(content as MCallHangupReject); } - this.calls.delete(content.call_id); + + // @ts-expect-error typescript thinks the state can't be 'ended' because we're + // inside the if block where it wasn't, but it could have changed because + // on[Hangup|Reject]Received are side-effecty. + if (call.state === CallState.Ended) this.calls.delete(content.call_id); } } return; From 1ac4cc4b1157c039991fda5fe50d1f6d82b03696 Mon Sep 17 00:00:00 2001 From: Andy Balaam Date: Tue, 22 Feb 2022 11:30:50 +0000 Subject: [PATCH 21/26] Bump matrix-events-sdk to 0.0.1-beta.7 (#2184) * Bump matrix-events-sdk to 0.0.1-beta.7 * Update lockfile for matrix-events-sdk-0.0.1-beta.7 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index fac5c90da62..d594cc1a75d 100644 --- a/package.json +++ b/package.json @@ -56,7 +56,7 @@ "bs58": "^4.0.1", "content-type": "^1.0.4", "loglevel": "^1.7.1", - "matrix-events-sdk": "^0.0.1-beta.6", + "matrix-events-sdk": "^0.0.1-beta.7", "p-retry": "^4.5.0", "qs": "^6.9.6", "request": "^2.88.2", diff --git a/yarn.lock b/yarn.lock index 86876acc576..2fdb6e01ac9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5452,10 +5452,10 @@ marked@^4.0.10: resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.12.tgz#2262a4e6fd1afd2f13557726238b69a48b982f7d" integrity sha512-hgibXWrEDNBWgGiK18j/4lkS6ihTe9sxtV4Q1OQppb/0zzyPSzoFANBa5MfsG/zgsWklmNnhm0XACZOH/0HBiQ== -matrix-events-sdk@^0.0.1-beta.6: - version "0.0.1-beta.6" - resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.6.tgz#9001090ed2e2bf29efc113d6b29871bcc6520749" - integrity sha512-VMqPXe3Bg4R9yC9PNqGv6bDFwWlVYadYxp0Ke1ihhXUCpGcx7e28kOYcqK2T3RxLXK4KK7VH4JRbY53Do3r+Fw== +matrix-events-sdk@^0.0.1-beta.7: + version "0.0.1-beta.7" + resolved "https://registry.yarnpkg.com/matrix-events-sdk/-/matrix-events-sdk-0.0.1-beta.7.tgz#5ffe45eba1f67cc8d7c2377736c728b322524934" + integrity sha512-9jl4wtWanUFSy2sr2lCjErN/oC8KTAtaeaozJtrgot1JiQcEI4Rda9OLgQ7nLKaqb4Z/QUx/fR3XpDzm5Jy1JA== matrix-mock-request@^1.2.3: version "1.2.3" From 4603d4e57812ea7a65e938505464c2a958baec72 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 22 Feb 2022 13:30:51 +0000 Subject: [PATCH 22/26] Prepare changelog for v15.6.0-rc.1 --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee22f17c2c7..4a1fb086afd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +Changes in [15.6.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v15.6.0-rc.1) (2022-02-22) +============================================================================================================ + +## ✨ Features + * Return send event response from MSC3089Branch.createNewVersion() ([\#2186](https://github.com/matrix-org/matrix-js-sdk/pull/2186)). + * Add functions to support refresh tokens ([\#2178](https://github.com/matrix-org/matrix-js-sdk/pull/2178)). + +## 🐛 Bug Fixes + * Fix bug where calls could break if rejected from somewhere else ([\#2189](https://github.com/matrix-org/matrix-js-sdk/pull/2189)). + * Fix camera stuck on after call transfer ([\#2188](https://github.com/matrix-org/matrix-js-sdk/pull/2188)). + * Fix synthetic read receipt handling ([\#2174](https://github.com/matrix-org/matrix-js-sdk/pull/2174)). Fixes vector-im/element-web#21016. + * Revert "Sign backup with cross-signing key when we reset it." ([\#2175](https://github.com/matrix-org/matrix-js-sdk/pull/2175)). + * Sign backup with cross-signing key when we reset it. ([\#2170](https://github.com/matrix-org/matrix-js-sdk/pull/2170)). + * Fix error in uploadContent() when file is empty under Node.js ([\#2155](https://github.com/matrix-org/matrix-js-sdk/pull/2155)). + * Check the backup info against the stored private key when determining trust. ([\#2167](https://github.com/matrix-org/matrix-js-sdk/pull/2167)). + * Back up keys before logging out ([\#2158](https://github.com/matrix-org/matrix-js-sdk/pull/2158)). Fixes vector-im/element-web#13151. + Changes in [15.5.2](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v15.5.2) (2022-02-17) ================================================================================================== From d595717e60bd412f0f84240532be2c72fd7219d2 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Tue, 22 Feb 2022 13:30:52 +0000 Subject: [PATCH 23/26] v15.6.0-rc.1 --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d594cc1a75d..410a92ffeca 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "15.5.2", + "version": "15.6.0-rc.1", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build", @@ -29,7 +29,7 @@ "keywords": [ "matrix-org" ], - "main": "./src/index.ts", + "main": "./lib/index.js", "browser": "./lib/browser-index.js", "matrix_src_main": "./src/index.ts", "matrix_src_browser": "./src/browser-index.js", @@ -115,5 +115,6 @@ "coverageReporters": [ "text" ] - } + }, + "typings": "./lib/index.d.ts" } From e408590c21ec2c5f2988cf5a5b92bac592b40411 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 24 Feb 2022 14:49:51 +0000 Subject: [PATCH 24/26] [Release] Fix bug with the /hierarchy API sending invalid requests (#2202) --- src/client.ts | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/client.ts b/src/client.ts index dafa4937f93..3cc5dfa6fb7 100644 --- a/src/client.ts +++ b/src/client.ts @@ -8628,12 +8628,21 @@ export class MatrixClient extends EventEmitter { $roomId: roomId, }); - return this.http.authedRequest(undefined, Method.Get, path, { + const queryParams: Record = { suggested_only: String(suggestedOnly), - max_depth: maxDepth?.toString(), - from: fromToken, - limit: limit?.toString(), - }, undefined, { + }; + + if (limit !== undefined) { + queryParams["limit"] = limit.toString(); + } + if (maxDepth !== undefined) { + queryParams["max_depth"] = maxDepth.toString(); + } + if (fromToken !== undefined) { + queryParams["from"] = fromToken; + } + + return this.http.authedRequest(undefined, Method.Get, path, queryParams, undefined, { prefix: "/_matrix/client/unstable/org.matrix.msc2946", }).catch(e => { if (e.errcode === "M_UNRECOGNIZED") { From a54471f737a38419f10060c2b34b6b192ae60f12 Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 28 Feb 2022 11:53:35 +0000 Subject: [PATCH 25/26] Prepare changelog for v15.6.0 --- CHANGELOG.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4a1fb086afd..824da060489 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +Changes in [15.6.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v15.6.0) (2022-02-28) +================================================================================================== + +## ✨ Features + * Return send event response from MSC3089Branch.createNewVersion() ([\#2186](https://github.com/matrix-org/matrix-js-sdk/pull/2186)). + * Add functions to support refresh tokens ([\#2178](https://github.com/matrix-org/matrix-js-sdk/pull/2178)). + +## 🐛 Bug Fixes + * [Release] Fix bug with the /hierarchy API sending invalid requests ([\#2202](https://github.com/matrix-org/matrix-js-sdk/pull/2202)). + * Fix bug where calls could break if rejected from somewhere else ([\#2189](https://github.com/matrix-org/matrix-js-sdk/pull/2189)). + * Fix camera stuck on after call transfer ([\#2188](https://github.com/matrix-org/matrix-js-sdk/pull/2188)). + * Fix synthetic read receipt handling ([\#2174](https://github.com/matrix-org/matrix-js-sdk/pull/2174)). Fixes vector-im/element-web#21016. + * Revert "Sign backup with cross-signing key when we reset it." ([\#2175](https://github.com/matrix-org/matrix-js-sdk/pull/2175)). + * Sign backup with cross-signing key when we reset it. ([\#2170](https://github.com/matrix-org/matrix-js-sdk/pull/2170)). + * Fix error in uploadContent() when file is empty under Node.js ([\#2155](https://github.com/matrix-org/matrix-js-sdk/pull/2155)). + * Check the backup info against the stored private key when determining trust. ([\#2167](https://github.com/matrix-org/matrix-js-sdk/pull/2167)). + * Back up keys before logging out ([\#2158](https://github.com/matrix-org/matrix-js-sdk/pull/2158)). Fixes vector-im/element-web#13151. + Changes in [15.6.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v15.6.0-rc.1) (2022-02-22) ============================================================================================================ From 901d53eb38c092a600c64f3041cdd25a79d1fd1c Mon Sep 17 00:00:00 2001 From: RiotRobot Date: Mon, 28 Feb 2022 16:16:51 +0000 Subject: [PATCH 26/26] v15.6.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 410a92ffeca..a6e15f006a9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "matrix-js-sdk", - "version": "15.6.0-rc.1", + "version": "15.6.0", "description": "Matrix Client-Server SDK for Javascript", "scripts": { "prepublishOnly": "yarn build",