From 4b1b6ddad661d7590fb39c4d6dc55d0e366df88d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 May 2023 16:54:22 +0100 Subject: [PATCH 01/38] Change version field to a string And add the notes on how the version field works. --- .../client-server-api/modules/voip_events.md | 12 + data/event-schemas/schema/m.call.answer.yaml | 2 +- .../schema/m.call.candidates.yaml | 2 +- data/event-schemas/schema/m.call.hangup.yaml | 2 +- data/event-schemas/schema/m.call.invite.yaml | 4 +- package-lock.json | 541 ++++++++---------- 6 files changed, 271 insertions(+), 292 deletions(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index 90471cae2..01f21825a 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -9,6 +9,18 @@ communication is supported (e.g. between two peers, or between a peer and a multi-point conferencing unit). This means that clients MUST only send call events to rooms with exactly two participants. +All VoIP events have a `version` field. This will be used to determine whether +devices support this new version of the protocol. For example, clients can use +this field to know whether to expect an `m.call.select_answer` event from their +opponent. If clients see events with `version` other than `0` or `"1"` +(including, for example, the numeric value `1`), they should treat these the +same as if they had `version` == `"1"`. + +Note that this implies any and all future versions of VoIP events should be +backwards-compatible. If it does become necessary to introduce a non +backwards-compatible VoIP spec, the intention would be for it to simply use a +separate set of event types. + #### Events {{% event-group group_name="m.call" %}} diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index e84cf6f88..ab68b3c9a 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -31,7 +31,7 @@ }, "version": { "type": "number", - "description": "The version of the VoIP specification this messages adheres to. This specification is version 0." + "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0" } }, "required": ["call_id", "answer", "version"] diff --git a/data/event-schemas/schema/m.call.candidates.yaml b/data/event-schemas/schema/m.call.candidates.yaml index 7426717c6..3ad1b7077 100644 --- a/data/event-schemas/schema/m.call.candidates.yaml +++ b/data/event-schemas/schema/m.call.candidates.yaml @@ -37,7 +37,7 @@ }, "version": { "type": "integer", - "description": "The version of the VoIP specification this messages adheres to. This specification is version 0." + "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." } }, "required": ["call_id", "candidates", "version"] diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 116d5af7d..bbcc8181a 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -14,7 +14,7 @@ }, "version": { "type": "integer", - "description": "The version of the VoIP specification this message adheres to. This specification is version 0." + "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." }, "reason": { "type": "string", diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index 65796e1e9..3fa236991 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -30,8 +30,8 @@ "required": ["type", "sdp"] }, "version": { - "type": "integer", - "description": "The version of the VoIP specification this message adheres to. This specification is version 0." + "type": "string", + "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." }, "lifetime": { "type": "integer", diff --git a/package-lock.json b/package-lock.json index 7b6ba5397..eb662f744 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,16 +11,17 @@ "devDependencies": { "autoprefixer": "^10.4.2", "node-fetch": "^2.6.7", - "postcss-cli": "^8.2.13" + "postcss": "^8.4.6", + "postcss-cli": "^9.1.0" } }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" }, "engines": { @@ -28,21 +29,21 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" }, "engines": { @@ -87,21 +88,15 @@ } }, "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", + "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", "dev": true, "engines": { - "node": ">= 4.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/autoprefixer": { @@ -207,14 +202,17 @@ } }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/color-convert": { @@ -236,9 +234,9 @@ "dev": true }, "node_modules/dependency-graph": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz", - "integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true, "engines": { "node": ">= 0.6.0" @@ -278,26 +276,25 @@ } }, "node_modules/fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" }, "engines": { - "node": ">=8" + "node": ">=8.6.0" } }, "node_modules/fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -329,18 +326,17 @@ } }, "node_modules/fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "dependencies": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", - "universalify": "^1.0.0" + "universalify": "^2.0.0" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/fsevents": { @@ -368,12 +364,12 @@ } }, "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -392,35 +388,35 @@ } }, "node_modules/globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", + "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", "dev": true, "dependencies": { - "array-union": "^2.1.0", + "array-union": "^3.0.1", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" + "fast-glob": "^3.2.7", + "ignore": "^5.1.9", + "merge2": "^1.4.1", + "slash": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "node_modules/ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true, "engines": { "node": ">= 4" @@ -478,12 +474,12 @@ } }, "node_modules/jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "dependencies": { - "universalify": "^1.0.0" + "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -508,16 +504,16 @@ } }, "node_modules/micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { - "node": ">=8" + "node": ">=8.6" } }, "node_modules/nanoid": { @@ -525,7 +521,6 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true, - "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -593,9 +588,9 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, "engines": { "node": ">=8.6" @@ -618,7 +613,6 @@ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz", "integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==", "dev": true, - "peer": true, "dependencies": { "nanoid": "^3.2.0", "picocolors": "^1.0.0", @@ -633,71 +627,34 @@ } }, "node_modules/postcss-cli": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-8.3.1.tgz", - "integrity": "sha512-leHXsQRq89S3JC9zw/tKyiVV2jAhnfQe0J8VI4eQQbUjwIe0XxVqLrR+7UsahF1s9wi4GlqP6SJ8ydf44cgF2Q==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.1.0.tgz", + "integrity": "sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==", "dev": true, "dependencies": { - "chalk": "^4.0.0", "chokidar": "^3.3.0", - "dependency-graph": "^0.9.0", - "fs-extra": "^9.0.0", - "get-stdin": "^8.0.0", - "globby": "^11.0.0", + "dependency-graph": "^0.11.0", + "fs-extra": "^10.0.0", + "get-stdin": "^9.0.0", + "globby": "^12.0.0", + "picocolors": "^1.0.0", "postcss-load-config": "^3.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", - "slash": "^3.0.0", - "yargs": "^16.0.0" + "slash": "^4.0.0", + "yargs": "^17.0.0" }, "bin": { - "postcss": "bin/postcss" + "postcss": "index.js" }, "engines": { - "node": ">=10" + "node": ">=12" }, "peerDependencies": { "postcss": "^8.0.0" } }, - "node_modules/postcss-cli/node_modules/chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/postcss-cli/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/postcss-cli/node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/postcss-load-config": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.1.tgz", @@ -758,6 +715,26 @@ "node": ">= 0.8" } }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -782,7 +759,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, "engines": { "node": ">=0.10.0" @@ -799,18 +776,38 @@ } }, "node_modules/run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } }, "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/source-map-js": { @@ -818,7 +815,6 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true, - "peer": true, "engines": { "node": ">=0.10.0" } @@ -874,9 +870,9 @@ "dev": true }, "node_modules/universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -934,57 +930,57 @@ } }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=12" } } }, "dependencies": { "@nodelib/fs.scandir": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", - "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", + "version": "2.1.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", + "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.3", + "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", - "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", + "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", - "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", + "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.3", + "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, @@ -1014,15 +1010,9 @@ } }, "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", + "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", "dev": true }, "autoprefixer": { @@ -1090,13 +1080,13 @@ } }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -1116,9 +1106,9 @@ "dev": true }, "dependency-graph": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz", - "integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==", + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", + "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", "dev": true }, "dir-glob": { @@ -1149,23 +1139,22 @@ "dev": true }, "fast-glob": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", - "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", + "version": "3.2.12", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", + "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.0", + "glob-parent": "^5.1.2", "merge2": "^1.3.0", - "micromatch": "^4.0.2", - "picomatch": "^2.2.1" + "micromatch": "^4.0.4" } }, "fastq": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", - "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", + "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -1187,15 +1176,14 @@ "dev": true }, "fs-extra": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", - "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "requires": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", - "universalify": "^1.0.0" + "universalify": "^2.0.0" } }, "fsevents": { @@ -1212,9 +1200,9 @@ "dev": true }, "get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", + "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", "dev": true }, "glob-parent": { @@ -1227,29 +1215,29 @@ } }, "globby": { - "version": "11.0.1", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", - "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", + "version": "12.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", + "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", "dev": true, "requires": { - "array-union": "^2.1.0", + "array-union": "^3.0.1", "dir-glob": "^3.0.1", - "fast-glob": "^3.1.1", - "ignore": "^5.1.4", - "merge2": "^1.3.0", - "slash": "^3.0.0" + "fast-glob": "^3.2.7", + "ignore": "^5.1.9", + "merge2": "^1.4.1", + "slash": "^4.0.0" } }, "graceful-fs": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", - "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "dev": true }, "ignore": { - "version": "5.1.8", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", - "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, "is-binary-path": { @@ -1289,13 +1277,13 @@ "dev": true }, "jsonfile": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", - "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^1.0.0" + "universalify": "^2.0.0" } }, "lilconfig": { @@ -1311,21 +1299,20 @@ "dev": true }, "micromatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", - "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.0.5" + "braces": "^3.0.2", + "picomatch": "^2.3.1" } }, "nanoid": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", - "dev": true, - "peer": true + "dev": true }, "node-fetch": { "version": "2.6.7", @@ -1367,9 +1354,9 @@ "dev": true }, "picomatch": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", - "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true }, "pify": { @@ -1383,7 +1370,6 @@ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz", "integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==", "dev": true, - "peer": true, "requires": { "nanoid": "^3.2.0", "picocolors": "^1.0.0", @@ -1391,50 +1377,23 @@ } }, "postcss-cli": { - "version": "8.3.1", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-8.3.1.tgz", - "integrity": "sha512-leHXsQRq89S3JC9zw/tKyiVV2jAhnfQe0J8VI4eQQbUjwIe0XxVqLrR+7UsahF1s9wi4GlqP6SJ8ydf44cgF2Q==", + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.1.0.tgz", + "integrity": "sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==", "dev": true, "requires": { - "chalk": "^4.0.0", "chokidar": "^3.3.0", - "dependency-graph": "^0.9.0", - "fs-extra": "^9.0.0", - "get-stdin": "^8.0.0", - "globby": "^11.0.0", + "dependency-graph": "^0.11.0", + "fs-extra": "^10.0.0", + "get-stdin": "^9.0.0", + "globby": "^12.0.0", + "picocolors": "^1.0.0", "postcss-load-config": "^3.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", - "slash": "^3.0.0", - "yargs": "^16.0.0" - }, - "dependencies": { - "chalk": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", - "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } + "slash": "^4.0.0", + "yargs": "^17.0.0" } }, "postcss-load-config": { @@ -1469,6 +1428,12 @@ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -1490,7 +1455,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true }, "reusify": { @@ -1500,23 +1465,25 @@ "dev": true }, "run-parallel": { - "version": "1.1.9", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", - "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", - "dev": true + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } }, "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", + "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", "dev": true }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, - "peer": true + "dev": true }, "string-width": { "version": "4.2.3", @@ -1560,9 +1527,9 @@ "dev": true }, "universalify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", - "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", "dev": true }, "webidl-conversions": { @@ -1605,24 +1572,24 @@ "dev": true }, "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.0", + "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" + "yargs-parser": "^21.1.1" } }, "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", "dev": true } } From ef15055e0aabf3481057811b514ad7f6582b8600 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 May 2023 16:59:31 +0100 Subject: [PATCH 02/38] Add spec requiring tracks to be within streams. --- content/client-server-api/modules/voip_events.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index 01f21825a..de49c7229 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -54,6 +54,19 @@ Or a rejected call: Calls are negotiated according to the WebRTC specification. +Clients are expected to send one stream with one track of kind `audio` (creating a +voice call). They can optionally send a second track in the same stream of kind +`video` (creating a video call). + +Clients implementing this specification use the first stream and will ignore +any streamless tracks. Note that in the Javascript WebRTC API, this means +`addTrack()` must be passed two parameters: a track and a stream, not just a +track, and in a video call the stream must be the same for both audio and video +track. + +A client may send other streams and tracks but the behaviour of the other party +with respect to presenting such streams and tracks is undefined. + ##### Glare "Glare" is a problem which occurs when two users call each other at From 0a8362fecae9949b32988b2f862a3b73cd9785a7 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 May 2023 17:08:53 +0100 Subject: [PATCH 03/38] Put streams spec in its own section --- content/client-server-api/modules/voip_events.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index de49c7229..eec1afc4e 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -54,6 +54,8 @@ Or a rejected call: Calls are negotiated according to the WebRTC specification. +##### Streams + Clients are expected to send one stream with one track of kind `audio` (creating a voice call). They can optionally send a second track in the same stream of kind `video` (creating a video call). From e49a85c81dc892c2032fdae076b6169736a5431d Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 2 May 2023 17:11:33 +0100 Subject: [PATCH 04/38] Add 'invitee' field --- content/client-server-api/modules/voip_events.md | 13 +++++++++++++ data/event-schemas/schema/m.call.invite.yaml | 4 ++++ 2 files changed, 17 insertions(+) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index eec1afc4e..b877450dc 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -69,6 +69,19 @@ track. A client may send other streams and tracks but the behaviour of the other party with respect to presenting such streams and tracks is undefined. +##### Invitees +The `invitee` field should be added whenever the call is intended for one +specific user , and should be set to the Matrix user ID of that user. Invites +without an `invitee` field are defined to be intended for any member of the +room other than the sender of the event. + +Clients should consider an incoming call if they see a non-expired invite event where the `invitee` field is either +absent or equal to their user's Matrix ID, however they should evaluate whether or not to ring based on their +user's trust relationship with the callers and/or where the call was placed. As a starting point, it is +suggested that clients ignore call invites from users in public rooms. It is strongly recommended that +when clients do not ring for an incoming call invite, they still display the call invite in the room and +annotate that it was ignored. + ##### Glare "Glare" is a problem which occurs when two users call each other at diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index 3fa236991..2da045bd0 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -36,6 +36,10 @@ "lifetime": { "type": "integer", "description": "The time in milliseconds that the invite is valid for. Once the invite age exceeds this value, clients should discard it. They should also no longer show the call as awaiting an answer in the UI." + }, + "invitee": { + "type": "string", + "description": "The ID of the user being called.", } }, "required": ["call_id", "offer", "version", "lifetime"] From 2abbc647d7775ccfce1b3d268bb7f44146fe0539 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 14:37:42 +0100 Subject: [PATCH 05/38] Add party_id --- .../client-server-api/modules/voip_events.md | 20 +++++++++++++++++++ data/event-schemas/schema/m.call.answer.yaml | 3 +++ .../schema/m.call.candidates.yaml | 3 +++ data/event-schemas/schema/m.call.hangup.yaml | 3 +++ data/event-schemas/schema/m.call.invite.yaml | 5 ++++- 5 files changed, 33 insertions(+), 1 deletion(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index b877450dc..8dbdaff48 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -21,6 +21,26 @@ backwards-compatible. If it does become necessary to introduce a non backwards-compatible VoIP spec, the intention would be for it to simply use a separate set of event types. +#### Party Identifiers +Whenever a client first participates in a new call, it generates a `party_id` for itself to use for the +duration of the call. This needs to be long enough that the chance of a collision between multiple devices +both generating an answer at the same time generating the same party ID is vanishingly small: 8 uppercase + +lowercase alphanumeric characters is recommended. Parties in the call are identified by the tuple of +`(user_id, party_id)`. + +The client adds a `party_id` field containing this ID to the top-level of the content of all VoIP events +it sends on the call, including `m.call.invite`. Clients use this to identify remote echo of their own +events: since a user may now call themselves, they can no longer ignore events from their own user. This +field also identifies different answers sent by different clients to an invite, and matches `m.call.candidates` +events to their respective answer/invite. + +A client implementation may choose to use the device ID used in end-to-end cryptography for this purpose, +or it may choose, for example, to use a different one for each call to avoid leaking information on which +devices were used in a call (in an unencrypted room) or if a single device (ie. access token) were used to +send signalling for more than one call party. + +A grammar for `party_id` is defined [below](#specify-exact-grammar-for-voip-ids). + #### Events {{% event-group group_name="m.call" %}} diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index ab68b3c9a..08058aed8 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -32,6 +32,9 @@ "version": { "type": "number", "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0" + }, + "party_id": { + "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " } }, "required": ["call_id", "answer", "version"] diff --git a/data/event-schemas/schema/m.call.candidates.yaml b/data/event-schemas/schema/m.call.candidates.yaml index 3ad1b7077..1ae83fca4 100644 --- a/data/event-schemas/schema/m.call.candidates.yaml +++ b/data/event-schemas/schema/m.call.candidates.yaml @@ -35,6 +35,9 @@ "required": ["candidate", "sdpMLineIndex", "sdpMid"] } }, + "party_id": { + "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + }, "version": { "type": "integer", "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index bbcc8181a..7342f1338 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -16,6 +16,9 @@ "type": "integer", "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." }, + "party_id": { + "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + }, "reason": { "type": "string", "description": "Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call. When there was an error in the call negotiation, this should be `ice_failed` for when ICE negotiation fails or `invite_timeout` for when the other party did not answer in time.", diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index 2da045bd0..bbfcbcdaf 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -33,6 +33,9 @@ "type": "string", "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." }, + "party_id": { + "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + }, "lifetime": { "type": "integer", "description": "The time in milliseconds that the invite is valid for. Once the invite age exceeds this value, clients should discard it. They should also no longer show the call as awaiting an answer in the UI." @@ -42,7 +45,7 @@ "description": "The ID of the user being called.", } }, - "required": ["call_id", "offer", "version", "lifetime"] + "required": ["call_id", "offer", "version", "lifetime", "party_id"] }, "type": { "type": "string", From 774968b65d679ad3741d20bd737923d5d968ce65 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 14:42:13 +0100 Subject: [PATCH 06/38] Remember how JSON works --- data/event-schemas/schema/m.call.answer.yaml | 3 ++- data/event-schemas/schema/m.call.candidates.yaml | 3 ++- data/event-schemas/schema/m.call.hangup.yaml | 3 ++- data/event-schemas/schema/m.call.invite.yaml | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index 08058aed8..be9783873 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -34,7 +34,8 @@ "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0" }, "party_id": { - "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + "type": "string", + "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " } }, "required": ["call_id", "answer", "version"] diff --git a/data/event-schemas/schema/m.call.candidates.yaml b/data/event-schemas/schema/m.call.candidates.yaml index 1ae83fca4..dc328b95a 100644 --- a/data/event-schemas/schema/m.call.candidates.yaml +++ b/data/event-schemas/schema/m.call.candidates.yaml @@ -36,7 +36,8 @@ } }, "party_id": { - "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + "type": "string", + "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " }, "version": { "type": "integer", diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 7342f1338..da871d367 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -17,7 +17,8 @@ "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." }, "party_id": { - "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + "type": "string", + "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " }, "reason": { "type": "string", diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index bbfcbcdaf..7f8618bfa 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -34,7 +34,8 @@ "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." }, "party_id": { - "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + "type": "string", + "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " }, "lifetime": { "type": "integer", From 93dd4e5c7ca78c4e645b6f58b9770372f2d4d27f Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 16:17:10 +0100 Subject: [PATCH 07/38] Add m.call.select_answer --- .../examples/m.call.select_answer.yaml | 10 ++++++ .../schema/m.call.select_answer.yaml | 35 +++++++++++++++++++ 2 files changed, 45 insertions(+) create mode 100644 data/event-schemas/examples/m.call.select_answer.yaml create mode 100644 data/event-schemas/schema/m.call.select_answer.yaml diff --git a/data/event-schemas/examples/m.call.select_answer.yaml b/data/event-schemas/examples/m.call.select_answer.yaml new file mode 100644 index 000000000..fbd6ad166 --- /dev/null +++ b/data/event-schemas/examples/m.call.select_answer.yaml @@ -0,0 +1,10 @@ +{ + "$ref": "core/room_event.json", + "type": "m.call.select_answer", + "content": { + "version" : "1", + "call_id": "12345", + "party_id": "67890", + "selected_party_id": "111213" + } +} diff --git a/data/event-schemas/schema/m.call.select_answer.yaml b/data/event-schemas/schema/m.call.select_answer.yaml new file mode 100644 index 000000000..88f32f1e6 --- /dev/null +++ b/data/event-schemas/schema/m.call.select_answer.yaml @@ -0,0 +1,35 @@ +{ + "type": "object", + "description": "This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.", + "allOf": [{ + "$ref": "core-event-schema/room_event.yaml" + }], + "properties": { + "content": { + "type": "object", + "properties": { + "call_id": { + "type": "string", + "description": "The ID of the call this event relates to." + }, + "version": { + "type": "integer", + "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." + }, + "party_id": { + "type": "string", + "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + }, + "selected_party_id": { + "type": "string", + "description": "The `party_id` field from the answer event that the caller chose." + }, + }, + "required": ["call_id", "version"] + }, + "type": { + "type": "string", + "enum": ["m.call.select_answer"] + } + } +} From b75850fd7853d80685cca3590ea036494cbcefd4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 16:21:31 +0100 Subject: [PATCH 08/38] Update examples --- data/event-schemas/examples/m.call.answer.yaml | 3 ++- data/event-schemas/examples/m.call.candidates.yaml | 3 ++- data/event-schemas/examples/m.call.hangup.yaml | 3 ++- data/event-schemas/examples/m.call.invite.yaml | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/data/event-schemas/examples/m.call.answer.yaml b/data/event-schemas/examples/m.call.answer.yaml index aaa4da714..78b488783 100644 --- a/data/event-schemas/examples/m.call.answer.yaml +++ b/data/event-schemas/examples/m.call.answer.yaml @@ -2,7 +2,8 @@ "$ref": "core/room_event.json", "type": "m.call.answer", "content": { - "version" : 0, + "version" : "1", + "party_id": "67890", "call_id": "12345", "answer": { "type" : "answer", diff --git a/data/event-schemas/examples/m.call.candidates.yaml b/data/event-schemas/examples/m.call.candidates.yaml index 8f1f807ad..23d0a1785 100644 --- a/data/event-schemas/examples/m.call.candidates.yaml +++ b/data/event-schemas/examples/m.call.candidates.yaml @@ -2,7 +2,8 @@ "$ref": "core/room_event.json", "type": "m.call.candidates", "content": { - "version" : 0, + "version" : "1", + "party_id": "67890", "call_id": "12345", "candidates": [ { diff --git a/data/event-schemas/examples/m.call.hangup.yaml b/data/event-schemas/examples/m.call.hangup.yaml index 295f16e48..062cd4aa8 100644 --- a/data/event-schemas/examples/m.call.hangup.yaml +++ b/data/event-schemas/examples/m.call.hangup.yaml @@ -2,7 +2,8 @@ "$ref": "core/room_event.json", "type": "m.call.hangup", "content": { - "version" : 0, + "version" : "1", + "party_id": "67890", "call_id": "12345" } } diff --git a/data/event-schemas/examples/m.call.invite.yaml b/data/event-schemas/examples/m.call.invite.yaml index fa482bd94..45600001e 100644 --- a/data/event-schemas/examples/m.call.invite.yaml +++ b/data/event-schemas/examples/m.call.invite.yaml @@ -2,7 +2,8 @@ "$ref": "core/room_event.json", "type": "m.call.invite", "content": { - "version" : 0, + "version" : "1", + "party_id": "67890", "call_id": "12345", "lifetime": 60000, "offer": { From d8dd3e0fb2720fa1289dd1b5352e9b91b1405d84 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 16:26:07 +0100 Subject: [PATCH 09/38] Add select_answer to call flow example diagram --- content/client-server-api/modules/voip_events.md | 1 + 1 file changed, 1 insertion(+) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index 8dbdaff48..b6925bc10 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -57,6 +57,7 @@ A call is set up with message events exchanged as follows: [..candidates..] --------> [Answers call] <--------------- m.call.answer + m.call.select_answer -----------> [Call is active and ongoing] <--------------- m.call.hangup ``` From ebed260bf4997acd474d2b027473a172942a965d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 16:32:48 +0100 Subject: [PATCH 10/38] Add m.call.reject --- .../event-schemas/examples/m.call.reject.yaml | 9 +++++ data/event-schemas/schema/m.call.reject.yaml | 40 +++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 data/event-schemas/examples/m.call.reject.yaml create mode 100644 data/event-schemas/schema/m.call.reject.yaml diff --git a/data/event-schemas/examples/m.call.reject.yaml b/data/event-schemas/examples/m.call.reject.yaml new file mode 100644 index 000000000..2014566c8 --- /dev/null +++ b/data/event-schemas/examples/m.call.reject.yaml @@ -0,0 +1,9 @@ +{ + "$ref": "core/room_event.json", + "type": "m.call.reject", + "content": { + "version" : "1", + "party_id": "67890", + "call_id": "12345" + } +} diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml new file mode 100644 index 000000000..1e2336a72 --- /dev/null +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -0,0 +1,40 @@ +{ + "type": "object", + "description": "If the `m.call.invite` event has `version` `\"1\"`, a client wishing to reject the call sends an `m.call.reject` event. This rejects the call on all devices, but if the calling device sees an `answer` before the `reject`, it disregards the reject event and carries on. The reject has a `party_id` just like an answer, and the caller sends a `select_answer` for it just like an answer. If another client had already sent an answer and sees the caller select the reject response instead of its answer, it ends the call. If the `m.call.invite` event has `version` `0`, the callee sends an `m.call.hangup` event. If the calling user chooses to end the call before setup is complete, the client sends `m.call.hangup` +as previously.", + "allOf": [{ + "$ref": "core-event-schema/room_event.yaml" + }], + "properties": { + "content": { + "type": "object", + "properties": { + "call_id": { + "type": "string", + "description": "The ID of the call this event relates to." + }, + "version": { + "type": "integer", + "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." + }, + "party_id": { + "type": "string", + "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " + }, + "reason": { + "type": "string", + "description": "Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call. When there was an error in the call negotiation, this should be `ice_failed` for when ICE negotiation fails or `invite_timeout` for when the other party did not answer in time.", + "enum": [ + "ice_failed", + "invite_timeout" + ] + } + }, + "required": ["call_id", "version", "party_id"] + }, + "type": { + "type": "string", + "enum": ["m.call.reject"] + } + } +} From efdb1ecb46417ea5607656b12025c29369a3abad Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 16:33:56 +0100 Subject: [PATCH 11/38] Make party_id required in other events --- data/event-schemas/schema/m.call.answer.yaml | 2 +- data/event-schemas/schema/m.call.candidates.yaml | 2 +- data/event-schemas/schema/m.call.hangup.yaml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index be9783873..d6caddc57 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -38,7 +38,7 @@ "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " } }, - "required": ["call_id", "answer", "version"] + "required": ["call_id", "answer", "version", "party_id"] }, "type": { "type": "string", diff --git a/data/event-schemas/schema/m.call.candidates.yaml b/data/event-schemas/schema/m.call.candidates.yaml index dc328b95a..2d5c55011 100644 --- a/data/event-schemas/schema/m.call.candidates.yaml +++ b/data/event-schemas/schema/m.call.candidates.yaml @@ -44,7 +44,7 @@ "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." } }, - "required": ["call_id", "candidates", "version"] + "required": ["call_id", "candidates", "version", "party_id"] }, "type": { "type": "string", diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index da871d367..f89b4b6b4 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -29,7 +29,7 @@ ] } }, - "required": ["call_id", "version"] + "required": ["call_id", "version", "party_id"] }, "type": { "type": "string", From f4b6c62daa5acc0d39f86ef643c75f1ee97540f6 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 3 May 2023 16:38:51 +0100 Subject: [PATCH 12/38] Add possible ways for client to handle an invite --- content/client-server-api/modules/voip_events.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index b6925bc10..ba94bd0d8 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -75,6 +75,15 @@ Or a rejected call: Calls are negotiated according to the WebRTC specification. +In response to an invoming invite, a client may do one of several things: + * Attempt to accept the call by sending an `m.call.answer`. + * Actively reject the call everywhere: send an `m.call.reject` as per above, which will stop the call from + ringing on all the user's devices and the caller's client will inform them that the user has + rejected their call. + * Ignore the call: send no events, but stop alerting the user about the call. The user's other + devices will continue to ring, and the caller's device will continue to indicate that the call + is ringing, and will time the call out in the normal way if no other device responds. + ##### Streams Clients are expected to send one stream with one track of kind `audio` (creating a From d9bd32d687ffd646934cd34f189d1ad650452708 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 10:29:38 +0100 Subject: [PATCH 13/38] Convert hangup & reject events to YAML So we can have a bulleted list in the description for the values of 'reason'. --- data/event-schemas/schema/m.call.hangup.yaml | 82 +++++++++--------- data/event-schemas/schema/m.call.reject.yaml | 90 +++++++++++--------- 2 files changed, 93 insertions(+), 79 deletions(-) diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index f89b4b6b4..14d03f98f 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -1,39 +1,43 @@ -{ - "type": "object", - "description": "Sent by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "call_id": { - "type": "string", - "description": "The ID of the call this event relates to." - }, - "version": { - "type": "integer", - "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." - }, - "party_id": { - "type": "string", - "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " - }, - "reason": { - "type": "string", - "description": "Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call. When there was an error in the call negotiation, this should be `ice_failed` for when ICE negotiation fails or `invite_timeout` for when the other party did not answer in time.", - "enum": [ - "ice_failed", - "invite_timeout" - ] - } - }, - "required": ["call_id", "version", "party_id"] - }, - "type": { - "type": "string", - "enum": ["m.call.hangup"] - } - } -} +--- +type: object +description: Sent by either party to signal their termination of the call. This can + be sent either once the call has has been established or before to abort the call. +allOf: +- "$ref": core-event-schema/room_event.yaml +properties: + content: + type: object + properties: + call_id: + type: string + description: The ID of the call this event relates to. + version: + type: integer + description: The version of the VoIP specification this message adheres to. + This specification is version 1. This field is a string such that experimental + implementations can use non-integer versions. This field was an integer + in the previous spec version and implementations must accept an integer + 0. + party_id: + type: string + description: 'This identifies the party that sent this event. A client may + choose to re-use the device ID from end-to-end cryptography for the value + of this field. ' + reason: + type: string + description: Optional error reason for the hangup. This should not be provided + when the user naturally ends or rejects the call. When there was an error + in the call negotiation, this should be `ice_failed` for when ICE negotiation + fails or `invite_timeout` for when the other party did not answer in time. + enum: + - ice_failed + - invite_timeout + required: + - call_id + - version + - party_id + type: + type: string + enum: + - m.call.hangup + diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index 1e2336a72..d06f7a574 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -1,40 +1,50 @@ -{ - "type": "object", - "description": "If the `m.call.invite` event has `version` `\"1\"`, a client wishing to reject the call sends an `m.call.reject` event. This rejects the call on all devices, but if the calling device sees an `answer` before the `reject`, it disregards the reject event and carries on. The reject has a `party_id` just like an answer, and the caller sends a `select_answer` for it just like an answer. If another client had already sent an answer and sees the caller select the reject response instead of its answer, it ends the call. If the `m.call.invite` event has `version` `0`, the callee sends an `m.call.hangup` event. If the calling user chooses to end the call before setup is complete, the client sends `m.call.hangup` -as previously.", - "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" - }], - "properties": { - "content": { - "type": "object", - "properties": { - "call_id": { - "type": "string", - "description": "The ID of the call this event relates to." - }, - "version": { - "type": "integer", - "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." - }, - "party_id": { - "type": "string", - "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " - }, - "reason": { - "type": "string", - "description": "Optional error reason for the hangup. This should not be provided when the user naturally ends or rejects the call. When there was an error in the call negotiation, this should be `ice_failed` for when ICE negotiation fails or `invite_timeout` for when the other party did not answer in time.", - "enum": [ - "ice_failed", - "invite_timeout" - ] - } - }, - "required": ["call_id", "version", "party_id"] - }, - "type": { - "type": "string", - "enum": ["m.call.reject"] - } - } -} +--- +type: object +description: If the `m.call.invite` event has `version` `"1"`, a client wishing to + reject the call sends an `m.call.reject` event. This rejects the call on all devices, + but if the calling device sees an `answer` before the `reject`, it disregards the + reject event and carries on. The reject has a `party_id` just like an answer, and + the caller sends a `select_answer` for it just like an answer. If another client + had already sent an answer and sees the caller select the reject response instead + of its answer, it ends the call. If the `m.call.invite` event has `version` `0`, + the callee sends an `m.call.hangup` event. If the calling user chooses to end the + call before setup is complete, the client sends `m.call.hangup` as previously. +allOf: +- "$ref": core-event-schema/room_event.yaml +properties: + content: + type: object + properties: + call_id: + type: string + description: The ID of the call this event relates to. + version: + type: integer + description: The version of the VoIP specification this message adheres to. + This specification is version 1. This field is a string such that experimental + implementations can use non-integer versions. This field was an integer + in the previous spec version and implementations must accept an integer + 0. + party_id: + type: string + description: 'This identifies the party that sent this event. A client may + choose to re-use the device ID from end-to-end cryptography for the value + of this field. ' + reason: + type: string + description: Optional error reason for the hangup. This should not be provided + when the user naturally ends or rejects the call. When there was an error + in the call negotiation, this should be `ice_failed` for when ICE negotiation + fails or `invite_timeout` for when the other party did not answer in time. + enum: + - ice_failed + - invite_timeout + required: + - call_id + - version + - party_id + type: + type: string + enum: + - m.call.reject + From 78719b4391f438a6e7a930442782d865e3fc66da Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 10:45:19 +0100 Subject: [PATCH 14/38] Add new reason codes to hangup & reject --- data/event-schemas/schema/m.call.hangup.yaml | 37 ++++++++++++++++---- data/event-schemas/schema/m.call.reject.yaml | 18 +++++++--- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 14d03f98f..5471abfde 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -1,7 +1,25 @@ --- type: object -description: Sent by either party to signal their termination of the call. This can +description: | + Sent by either party to signal their termination of the call. This can be sent either once the call has has been established or before to abort the call. + + The meanings of the `reason` field are as follows: + * `ice_timeout`: The connection failed after some media was exchanged (as opposed to current + * `ice_failed` which means no media connection could be established). Note that, in the case of + an ICE renegotiation, a client should be sure to send `ice_timeout` rather than `ice_failed` if + media had previously been received successfully, even if the ICE renegotiation itself failed. + * `invite_timeout`: The other party did not answer in time. + * `user_hangup`: Clients must now send this code when the user chooses to end the call, although + for backwards compatability with version 0, a clients should treat an absence of the `reason` + field as `user_hangup`. + * `user_media_failed`: The client was unable to start capturing media in such a way that it is unable + to continue the call. + * `user_busy`: The user is busy. Note that this exists primarily for bridging to other networks such + as the PSTN. A Matrix client that receives a call whilst already in a call would not generally reject + the new call unless the user had specifically chosen to do so. + * `unknown_error`: Some other failure occurred that meant the client was unable to continue the call + rather than the user choosing to end it. allOf: - "$ref": core-event-schema/room_event.yaml properties: @@ -20,22 +38,27 @@ properties: 0. party_id: type: string - description: 'This identifies the party that sent this event. A client may + description: This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value - of this field. ' + of this field. reason: type: string - description: Optional error reason for the hangup. This should not be provided - when the user naturally ends or rejects the call. When there was an error - in the call negotiation, this should be `ice_failed` for when ICE negotiation - fails or `invite_timeout` for when the other party did not answer in time. + description: Reason for the hangup. Note that this was optional in + previous previous versions of the spec, so a missing value should be + treated as `user_hangup`. enum: + - ice_timeout - ice_failed - invite_timeout + - user_hangup + - user_media_failed + - user_busy + - unknown_error required: - call_id - version - party_id + - reason type: type: string enum: diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index d06f7a574..7a027379b 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -1,6 +1,7 @@ --- type: object -description: If the `m.call.invite` event has `version` `"1"`, a client wishing to +description: | + If the `m.call.invite` event has `version` `"1"`, a client wishing to reject the call sends an `m.call.reject` event. This rejects the call on all devices, but if the calling device sees an `answer` before the `reject`, it disregards the reject event and carries on. The reject has a `party_id` just like an answer, and @@ -9,6 +10,8 @@ description: If the `m.call.invite` event has `version` `"1"`, a client wishing of its answer, it ends the call. If the `m.call.invite` event has `version` `0`, the callee sends an `m.call.hangup` event. If the calling user chooses to end the call before setup is complete, the client sends `m.call.hangup` as previously. + + The meanings of the `reason` codes are the same as in [`m.call.hangup`](#mcallhangup). allOf: - "$ref": core-event-schema/room_event.yaml properties: @@ -32,17 +35,22 @@ properties: of this field. ' reason: type: string - description: Optional error reason for the hangup. This should not be provided - when the user naturally ends or rejects the call. When there was an error - in the call negotiation, this should be `ice_failed` for when ICE negotiation - fails or `invite_timeout` for when the other party did not answer in time. + description: Reason for the hangup. Note that this was optional in + previous previous versions of the spec, so a missing value should be + treated as `user_hangup`. enum: + - ice_timeout - ice_failed - invite_timeout + - user_hangup + - user_media_failed + - user_busy + - unknown_error required: - call_id - version - party_id + - reason type: type: string enum: From ecb30706bf645f226ec2150f370b447708b60206 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 12:00:13 +0100 Subject: [PATCH 15/38] Add m.call.negotiate --- .../examples/m.call.negotiate.yaml | 14 +++ .../schema/m.call.negotiate.yaml | 90 +++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 data/event-schemas/examples/m.call.negotiate.yaml create mode 100644 data/event-schemas/schema/m.call.negotiate.yaml diff --git a/data/event-schemas/examples/m.call.negotiate.yaml b/data/event-schemas/examples/m.call.negotiate.yaml new file mode 100644 index 000000000..f4ad8587e --- /dev/null +++ b/data/event-schemas/examples/m.call.negotiate.yaml @@ -0,0 +1,14 @@ +{ + "$ref": "core/room_event.json", + "type": "m.call.negotiate", + "content": { + "version" : "1", + "party_id": "67890", + "call_id": "12345", + "lifetime": 10000, + "offer": { + "type" : "offer", + "sdp" : "v=0\r\no=- 6584580628695956864 2 IN IP4 127.0.0.1[...]" + } + } +} diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml new file mode 100644 index 000000000..af197c38f --- /dev/null +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -0,0 +1,90 @@ +--- +type: object +description: | + Provides SDP negotiation semantics for media pause, hold/resume, ICE restarts + and voice/video call up/downgrading. Clients should implement & honour hold + functionality as per WebRTC's recommendation: + https://www.w3.org/TR/webrtc/#hold-functionality + + If both the invite event and the accepted answer event have `version` equal + to `"1"`, either party may send `m.call.negotiate` with a `description` field + to offer new SDP to the other party. This event has `call_id` with the ID of + the call and `party_id` equal to the client's party ID for that call. The + caller ignores any negotiate events with `party_id` + `user_id` tuple not + equal to that of the answer it accepted and the callee ignores any negotiate + events with `party_id` + `user_id` tuple not equal to that of the caller. + Clients should use the `party_id` field to ignore the remote echo of their + own negotiate events. + + This has a `lifetime` field as in `m.call.invite`, after which the sender of + the negotiate event should consider the negotiation failed (timed out) and + the recipient should ignore it. + + The `description` field is the same as the `offer` field in `m.call.invite` + and `answer` field in `m.call.answer` and is an `RTCSessionDescriptionInit` + object as per https://www.w3.org/TR/webrtc/#dom-rtcsessiondescriptioninit. + + Once an `m.call.negotiate` event is received, the client must respond with + another `m.call.negotiate` event, with the SDP answer (with `"type": "answer"`) + in the `description` property. + + This MSC also proposes clarifying the `m.call.invite` and `m.call.answer` + events to state that the `offer` and `answer` fields respectively are objects + of type `RTCSessionDescriptionInit`. Hence the `type` field, whilst + redundant in these events, is included for ease of working with the WebRTC + API and is mandatory. Receiving clients should not attempt to validate the + `type` field, but simply pass the object into the WebRTC API. +allOf: +- "$ref": core-event-schema/room_event.yaml +properties: + content: + type: object + properties: + call_id: + type: string + description: The ID of the call this event relates to. + version: + type: integer + description: The version of the VoIP specification this message adheres to. + This specification is version 1. This field is a string such that experimental + implementations can use non-integer versions. This field was an integer + in the previous spec version and implementations must accept an integer + 0. + party_id: + type: string + description: This identifies the party that sent this event. A client may + choose to re-use the device ID from end-to-end cryptography for the value + of this field. + offer: + type: object + title: Offer + description: The session description object + properties: + type: + type: string + enum: + - offer + description: The type of session description. + sdp: + type: string + description: The SDP text of the session description. + required: + - type + - sdp + lifetime: + type: integer + description: The time in milliseconds that the invite is valid for. + Once the invite age exceeds this value, clients should discard it. + They should also no longer show the call as awaiting an answer in the + UI. + required: + - call_id + - version + - party_id + - offer + - lifetime + type: + type: string + enum: + - m.call.negotiate + From 2801c6f5a5a22033383fc9368e6c16773927cf13 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 12:09:39 +0100 Subject: [PATCH 16/38] Add other sections --- .../client-server-api/modules/voip_events.md | 79 +++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index ba94bd0d8..b14aba381 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -41,6 +41,85 @@ send signalling for more than one call party. A grammar for `party_id` is defined [below](#specify-exact-grammar-for-voip-ids). +#### Politeness +In line with WebRTC perfect negotiation (https://w3c.github.io/webrtc-pc/#perfect-negotiation-example) +there are rules to establish which party is polite in the process of renegotiation. The callee is +always the polite party. In a glare situation, the politenes of a party is therefore determined by +whether the inbound or outbound call is used: if a client discards its outbound call in favour of +an inbound call, it becomes the polite party. + +#### Call Event Liveness +`m.call.invite` contains a `lifetime` field that indicates how long the offer is valid for. When +a client receives an invite, it should use the event's `age` field in the sync response plus the +time since it received the event from the homeserver to determine whether the invite is still valid. +The use of the `age` field ensures that incorrect clocks on client devices don't break calls. + +If the invite is still valid *and will remain valid for long enough for the user to accept the call*, +it should signal an incoming call. The amount of time allowed for the user to accept the call may +vary between clients. For example, it may be longer on a locked mobile device than on an unlocked +desktop device. + +The client should only signal an incoming call in a given room once it has completed processing the +entire sync response and, for encrypted rooms, attempted to decrypt all encrypted events in the +sync response for that room. This ensures that if the sync response contains subsequent events that +indicate the call has been hung up, rejected, or answered elsewhere, the client does not signal it. + +If on startup, after processing locally stored events, the client determines that there is an invite +that is still valid, it should still signal it but only after it has completed a sync from the homeserver. + +The minimal recommended lifetime is 90 seconds - this should give the user enough time to actually pick +up the call. + +#### ICE Candidate Batching +Clients should aim to send a small number of candidate events, with guidelines: + * ICE candidates which can be discovered immediately or almost immediately in the invite/answer + event itself (eg. host candidates). If server reflexive or relay candiates can be gathered in + a sufficiently short period of time, these should be sent here too. A delay of around 200ms is + suggested as a starting point. + * The client should then allow some time for further candidates to be gathered in order to batch them, + rather than sending each candidate as it arrives. A starting point of 2 seconds after sending the + invite or 500ms after sending the answer is suggested as a starting point (since a delay is natural + anyway after the invite whilst the client waits for the user to accept it). + +#### End-of-candidates +An ICE candidate whose value is the empty string means that no more ICE candidates will +be sent. Clients must send such a candidate in an `m.call.candidates` message. +The WebRTC spec requires browsers to generate such a candidate, however note that at time of writing, +not all browsers do (Chrome does not, but does generate an `icegatheringstatechange` event). The +client should send any remaining candidates once candidate generation finishes, ignoring timeouts above. +This allows bridges to batch the candidates together when bridging to protocols that don't support +trickle ICE. + +#### DTMF +Matrix clients can send DTMF as specified by WebRTC. The WebRTC standard as of August +2020 does not support receiving DTMF but a Matrix client can receive and interpret the DTMF sent +in the RTP payload. + +#### Grammar for VoIP IDs +`call_id`s and `party_id` are explicitly defined to be between 1 and 255 characters long, consisting +of the characters `[0-9a-zA-Z._~-]`. + +(Note that this matches the grammar of 'opaque IDs' from +[MSC1597](https://github.com/matrix-org/matrix-spec-proposals/blob/rav/proposals/id_grammar/proposals/1597-id-grammar.md#opaque-ids), +and that of the `id` property of the + [`m.login.sso` flow schema](https://spec.matrix.org/v1.5/client-server-api/#definition-mloginsso-flow-schema).) + +#### Behaviour on Room Leave +If the client sees the user it is in a call with leave the room, the client should treat this +as a hangup event for any calls that are in progress. No specific requirement is given for the +situation where a client has sent an invite and the invitee leaves the room, but the client may +wish to treat it as a rejection if there are no more users in the room who could answer the call +(eg. the user is now alone or the `invitee` field was set on the invite). + +The same behaviour applies when a client is looking at historic calls. + +#### Supported Codecs +The Matrix spec does not mandate particular audio or video codecs, but instead defers to the +WebRTC spec. A compliant matrix VoIP client will behave in the same way as a supported 'browser' +in terms of what codecs it supports and what variants thereof. The latest WebRTC specification +applies, so clients should keep up to date with new versions of the WebRTC specification whether +or not there have been any changes to the Matrix spec. + #### Events {{% event-group group_name="m.call" %}} From 6a058d04231f621affee6e53e5faaf818e809cb0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 12:11:56 +0100 Subject: [PATCH 17/38] Revert changes to package lock --- package-lock.json | 541 ++++++++++++++++++++++++---------------------- 1 file changed, 287 insertions(+), 254 deletions(-) diff --git a/package-lock.json b/package-lock.json index eb662f744..7b6ba5397 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,17 +11,16 @@ "devDependencies": { "autoprefixer": "^10.4.2", "node-fetch": "^2.6.7", - "postcss": "^8.4.6", - "postcss-cli": "^9.1.0" + "postcss-cli": "^8.2.13" } }, "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", "dev": true, "dependencies": { - "@nodelib/fs.stat": "2.0.5", + "@nodelib/fs.stat": "2.0.3", "run-parallel": "^1.1.9" }, "engines": { @@ -29,21 +28,21 @@ } }, "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "dev": true, "engines": { "node": ">= 8" } }, "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", "dev": true, "dependencies": { - "@nodelib/fs.scandir": "2.1.5", + "@nodelib/fs.scandir": "2.1.3", "fastq": "^1.6.0" }, "engines": { @@ -88,15 +87,21 @@ } }, "node_modules/array-union": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", - "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" + } + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" } }, "node_modules/autoprefixer": { @@ -202,17 +207,14 @@ } }, "node_modules/cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", + "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" } }, "node_modules/color-convert": { @@ -234,9 +236,9 @@ "dev": true }, "node_modules/dependency-graph": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz", + "integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==", "dev": true, "engines": { "node": ">= 0.6.0" @@ -276,25 +278,26 @@ } }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", + "glob-parent": "^5.1.0", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" }, "engines": { - "node": ">=8.6.0" + "node": ">=8" } }, "node_modules/fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", "dev": true, "dependencies": { "reusify": "^1.0.4" @@ -326,17 +329,18 @@ } }, "node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", "dev": true, "dependencies": { + "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "universalify": "^1.0.0" }, "engines": { - "node": ">=12" + "node": ">=10" } }, "node_modules/fsevents": { @@ -364,12 +368,12 @@ } }, "node_modules/get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true, "engines": { - "node": ">=12" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -388,35 +392,35 @@ } }, "node_modules/globby": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", - "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "dev": true, "dependencies": { - "array-union": "^3.0.1", + "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.2.7", - "ignore": "^5.1.9", - "merge2": "^1.4.1", - "slash": "^4.0.0" + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">=10" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "node_modules/ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true, "engines": { "node": ">= 4" @@ -474,12 +478,12 @@ } }, "node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", + "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", "dev": true, "dependencies": { - "universalify": "^2.0.0" + "universalify": "^1.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" @@ -504,16 +508,16 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "braces": "^3.0.1", + "picomatch": "^2.0.5" }, "engines": { - "node": ">=8.6" + "node": ">=8" } }, "node_modules/nanoid": { @@ -521,6 +525,7 @@ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", "dev": true, + "peer": true, "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -588,9 +593,9 @@ "dev": true }, "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true, "engines": { "node": ">=8.6" @@ -613,6 +618,7 @@ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz", "integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==", "dev": true, + "peer": true, "dependencies": { "nanoid": "^3.2.0", "picocolors": "^1.0.0", @@ -627,34 +633,71 @@ } }, "node_modules/postcss-cli": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.1.0.tgz", - "integrity": "sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-8.3.1.tgz", + "integrity": "sha512-leHXsQRq89S3JC9zw/tKyiVV2jAhnfQe0J8VI4eQQbUjwIe0XxVqLrR+7UsahF1s9wi4GlqP6SJ8ydf44cgF2Q==", "dev": true, "dependencies": { + "chalk": "^4.0.0", "chokidar": "^3.3.0", - "dependency-graph": "^0.11.0", - "fs-extra": "^10.0.0", - "get-stdin": "^9.0.0", - "globby": "^12.0.0", - "picocolors": "^1.0.0", + "dependency-graph": "^0.9.0", + "fs-extra": "^9.0.0", + "get-stdin": "^8.0.0", + "globby": "^11.0.0", "postcss-load-config": "^3.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", - "slash": "^4.0.0", - "yargs": "^17.0.0" + "slash": "^3.0.0", + "yargs": "^16.0.0" }, "bin": { - "postcss": "index.js" + "postcss": "bin/postcss" }, "engines": { - "node": ">=12" + "node": ">=10" }, "peerDependencies": { "postcss": "^8.0.0" } }, + "node_modules/postcss-cli/node_modules/chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/postcss-cli/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/postcss-cli/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/postcss-load-config": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-3.1.1.tgz", @@ -715,26 +758,6 @@ "node": ">= 0.8" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -759,7 +782,7 @@ "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true, "engines": { "node": ">=0.10.0" @@ -776,38 +799,18 @@ } }, "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true }, "node_modules/slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true, "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=8" } }, "node_modules/source-map-js": { @@ -815,6 +818,7 @@ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", "dev": true, + "peer": true, "engines": { "node": ">=0.10.0" } @@ -870,9 +874,9 @@ "dev": true }, "node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", "dev": true, "engines": { "node": ">= 10.0.0" @@ -930,57 +934,57 @@ } }, "node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "dependencies": { - "cliui": "^8.0.1", + "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^4.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^20.2.2" }, "engines": { - "node": ">=12" + "node": ">=10" } }, "node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true, "engines": { - "node": ">=12" + "node": ">=10" } } }, "dependencies": { "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", "dev": true, "requires": { - "@nodelib/fs.stat": "2.0.5", + "@nodelib/fs.stat": "2.0.3", "run-parallel": "^1.1.9" } }, "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "dev": true }, "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", "dev": true, "requires": { - "@nodelib/fs.scandir": "2.1.5", + "@nodelib/fs.scandir": "2.1.3", "fastq": "^1.6.0" } }, @@ -1010,9 +1014,15 @@ } }, "array-union": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-3.0.1.tgz", - "integrity": "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", "dev": true }, "autoprefixer": { @@ -1080,13 +1090,13 @@ } }, "cliui": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", - "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", + "strip-ansi": "^6.0.0", "wrap-ansi": "^7.0.0" } }, @@ -1106,9 +1116,9 @@ "dev": true }, "dependency-graph": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz", - "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==", + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.9.0.tgz", + "integrity": "sha512-9YLIBURXj4DJMFALxXw9K3Y3rwb5Fk0X5/8ipCzaN84+gKxoHK43tVKRNakCQbiEx07E8Uwhuq21BpUagFhZ8w==", "dev": true }, "dir-glob": { @@ -1139,22 +1149,23 @@ "dev": true }, "fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", + "glob-parent": "^5.1.0", "merge2": "^1.3.0", - "micromatch": "^4.0.4" + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" } }, "fastq": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", - "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", "dev": true, "requires": { "reusify": "^1.0.4" @@ -1176,14 +1187,15 @@ "dev": true }, "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.0.1.tgz", + "integrity": "sha512-h2iAoN838FqAFJY2/qVpzFXy+EBxfVE220PalAqQLDVsFOHLJrZvut5puAbCdNv6WJk+B8ihI+k0c7JK5erwqQ==", "dev": true, "requires": { + "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", - "universalify": "^2.0.0" + "universalify": "^1.0.0" } }, "fsevents": { @@ -1200,9 +1212,9 @@ "dev": true }, "get-stdin": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz", - "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, "glob-parent": { @@ -1215,29 +1227,29 @@ } }, "globby": { - "version": "12.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-12.2.0.tgz", - "integrity": "sha512-wiSuFQLZ+urS9x2gGPl1H5drc5twabmm4m2gTR27XDFyjUHJUNsS8o/2aKyIF6IoBaR630atdher0XJ5g6OMmA==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "dev": true, "requires": { - "array-union": "^3.0.1", + "array-union": "^2.1.0", "dir-glob": "^3.0.1", - "fast-glob": "^3.2.7", - "ignore": "^5.1.9", - "merge2": "^1.4.1", - "slash": "^4.0.0" + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" } }, "graceful-fs": { - "version": "4.2.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", - "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", "dev": true }, "ignore": { - "version": "5.2.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", - "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, "is-binary-path": { @@ -1277,13 +1289,13 @@ "dev": true }, "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.0.1.tgz", + "integrity": "sha512-jR2b5v7d2vIOust+w3wtFKZIfpC2pnRmFAhAC/BuweZFQR8qZzxH1OyrQ10HmdVYiXWkYUqPVsz91cG7EL2FBg==", "dev": true, "requires": { "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" + "universalify": "^1.0.0" } }, "lilconfig": { @@ -1299,20 +1311,21 @@ "dev": true }, "micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz", + "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==", "dev": true, "requires": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" + "braces": "^3.0.1", + "picomatch": "^2.0.5" } }, "nanoid": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.2.0.tgz", "integrity": "sha512-fmsZYa9lpn69Ad5eDn7FMcnnSR+8R34W9qJEijxYhTbfOWzr22n1QxCMzXLK+ODyW2973V3Fux959iQoUxzUIA==", - "dev": true + "dev": true, + "peer": true }, "node-fetch": { "version": "2.6.7", @@ -1354,9 +1367,9 @@ "dev": true }, "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, "pify": { @@ -1370,6 +1383,7 @@ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.6.tgz", "integrity": "sha512-OovjwIzs9Te46vlEx7+uXB0PLijpwjXGKXjVGGPIGubGpq7uh5Xgf6D6FiJ/SzJMBosHDp6a2hiXOS97iBXcaA==", "dev": true, + "peer": true, "requires": { "nanoid": "^3.2.0", "picocolors": "^1.0.0", @@ -1377,23 +1391,50 @@ } }, "postcss-cli": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-9.1.0.tgz", - "integrity": "sha512-zvDN2ADbWfza42sAnj+O2uUWyL0eRL1V+6giM2vi4SqTR3gTYy8XzcpfwccayF2szcUif0HMmXiEaDv9iEhcpw==", + "version": "8.3.1", + "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-8.3.1.tgz", + "integrity": "sha512-leHXsQRq89S3JC9zw/tKyiVV2jAhnfQe0J8VI4eQQbUjwIe0XxVqLrR+7UsahF1s9wi4GlqP6SJ8ydf44cgF2Q==", "dev": true, "requires": { + "chalk": "^4.0.0", "chokidar": "^3.3.0", - "dependency-graph": "^0.11.0", - "fs-extra": "^10.0.0", - "get-stdin": "^9.0.0", - "globby": "^12.0.0", - "picocolors": "^1.0.0", + "dependency-graph": "^0.9.0", + "fs-extra": "^9.0.0", + "get-stdin": "^8.0.0", + "globby": "^11.0.0", "postcss-load-config": "^3.0.0", "postcss-reporter": "^7.0.0", "pretty-hrtime": "^1.0.3", "read-cache": "^1.0.0", - "slash": "^4.0.0", - "yargs": "^17.0.0" + "slash": "^3.0.0", + "yargs": "^16.0.0" + }, + "dependencies": { + "chalk": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } } }, "postcss-load-config": { @@ -1428,12 +1469,6 @@ "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, "read-cache": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", @@ -1455,7 +1490,7 @@ "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", "dev": true }, "reusify": { @@ -1465,25 +1500,23 @@ "dev": true }, "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true }, "slash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-4.0.0.tgz", - "integrity": "sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", "dev": true }, "source-map-js": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true + "dev": true, + "peer": true }, "string-width": { "version": "4.2.3", @@ -1527,9 +1560,9 @@ "dev": true }, "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-1.0.0.tgz", + "integrity": "sha512-rb6X1W158d7pRQBg5gkR8uPaSfiids68LTJQYOtEUhoJUWBdaQHsuT/EUduxXYxcrt4r5PJ4fuHW1MHT6p0qug==", "dev": true }, "webidl-conversions": { @@ -1572,24 +1605,24 @@ "dev": true }, "yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", "dev": true, "requires": { - "cliui": "^8.0.1", + "cliui": "^7.0.2", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", - "string-width": "^4.2.3", + "string-width": "^4.2.0", "y18n": "^5.0.5", - "yargs-parser": "^21.1.1" + "yargs-parser": "^20.2.2" } }, "yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "version": "20.2.9", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", + "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", "dev": true } } From e741e3a7af4910fb557ffbedb5f0db46a1e76f69 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 12:16:52 +0100 Subject: [PATCH 18/38] Typos --- content/client-server-api/modules/voip_events.md | 2 +- data/event-schemas/schema/m.call.hangup.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index b14aba381..b18f7d7f7 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -73,7 +73,7 @@ up the call. #### ICE Candidate Batching Clients should aim to send a small number of candidate events, with guidelines: * ICE candidates which can be discovered immediately or almost immediately in the invite/answer - event itself (eg. host candidates). If server reflexive or relay candiates can be gathered in + event itself (eg. host candidates). If server reflexive or relay candidates can be gathered in a sufficiently short period of time, these should be sent here too. A delay of around 200ms is suggested as a starting point. * The client should then allow some time for further candidates to be gathered in order to batch them, diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 5471abfde..1754b2de8 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -11,7 +11,7 @@ description: | media had previously been received successfully, even if the ICE renegotiation itself failed. * `invite_timeout`: The other party did not answer in time. * `user_hangup`: Clients must now send this code when the user chooses to end the call, although - for backwards compatability with version 0, a clients should treat an absence of the `reason` + for backwards compatibility with version 0, a clients should treat an absence of the `reason` field as `user_hangup`. * `user_media_failed`: The client was unable to start capturing media in such a way that it is unable to continue the call. From a7f5b8f8f41e32d4de9cd560199288ab76e55fc4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 12:20:53 +0100 Subject: [PATCH 19/38] Fix type of other version fields, fix anchor. --- content/client-server-api/modules/voip_events.md | 2 +- data/event-schemas/schema/m.call.answer.yaml | 2 +- data/event-schemas/schema/m.call.candidates.yaml | 2 +- data/event-schemas/schema/m.call.hangup.yaml | 2 +- data/event-schemas/schema/m.call.negotiate.yaml | 2 +- data/event-schemas/schema/m.call.reject.yaml | 2 +- data/event-schemas/schema/m.call.select_answer.yaml | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index b18f7d7f7..e269d640c 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -39,7 +39,7 @@ or it may choose, for example, to use a different one for each call to avoid lea devices were used in a call (in an unencrypted room) or if a single device (ie. access token) were used to send signalling for more than one call party. -A grammar for `party_id` is defined [below](#specify-exact-grammar-for-voip-ids). +A grammar for `party_id` is defined [below](#grammar-for-voip-ids). #### Politeness In line with WebRTC perfect negotiation (https://w3c.github.io/webrtc-pc/#perfect-negotiation-example) diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index d6caddc57..7037f2543 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -30,7 +30,7 @@ "required": ["type", "sdp"] }, "version": { - "type": "number", + "type": "string", "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0" }, "party_id": { diff --git a/data/event-schemas/schema/m.call.candidates.yaml b/data/event-schemas/schema/m.call.candidates.yaml index 2d5c55011..8937fc1bd 100644 --- a/data/event-schemas/schema/m.call.candidates.yaml +++ b/data/event-schemas/schema/m.call.candidates.yaml @@ -40,7 +40,7 @@ "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " }, "version": { - "type": "integer", + "type": "string", "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." } }, diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 1754b2de8..e9fba9003 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -30,7 +30,7 @@ properties: type: string description: The ID of the call this event relates to. version: - type: integer + type: string description: The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index af197c38f..92aecef4b 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -44,7 +44,7 @@ properties: type: string description: The ID of the call this event relates to. version: - type: integer + type: string description: The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index 7a027379b..051b3f1e1 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -22,7 +22,7 @@ properties: type: string description: The ID of the call this event relates to. version: - type: integer + type: string description: The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer diff --git a/data/event-schemas/schema/m.call.select_answer.yaml b/data/event-schemas/schema/m.call.select_answer.yaml index 88f32f1e6..a28a74650 100644 --- a/data/event-schemas/schema/m.call.select_answer.yaml +++ b/data/event-schemas/schema/m.call.select_answer.yaml @@ -13,7 +13,7 @@ "description": "The ID of the call this event relates to." }, "version": { - "type": "integer", + "type": "string", "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." }, "party_id": { From c079875928d7575b8ee474e0d3d824a59b12af1d Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 12:29:59 +0100 Subject: [PATCH 20/38] Add newsfragment --- changelogs/client_server/newsfragments/1511.feature | 1 + 1 file changed, 1 insertion(+) create mode 100644 changelogs/client_server/newsfragments/1511.feature diff --git a/changelogs/client_server/newsfragments/1511.feature b/changelogs/client_server/newsfragments/1511.feature new file mode 100644 index 000000000..d3526b8ee --- /dev/null +++ b/changelogs/client_server/newsfragments/1511.feature @@ -0,0 +1 @@ +Update VoIP spec for [MSC2746](https://github.com/matrix-org/matrix-spec-proposals/pull/2746). From af22989a247db0bb8ff6b204cd426a250d1307e2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 4 May 2023 12:30:18 +0100 Subject: [PATCH 21/38] Fix reason in hangup/reject --- data/event-schemas/examples/m.call.hangup.yaml | 3 ++- data/event-schemas/schema/m.call.reject.yaml | 1 - 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/data/event-schemas/examples/m.call.hangup.yaml b/data/event-schemas/examples/m.call.hangup.yaml index 062cd4aa8..a505bc367 100644 --- a/data/event-schemas/examples/m.call.hangup.yaml +++ b/data/event-schemas/examples/m.call.hangup.yaml @@ -4,6 +4,7 @@ "content": { "version" : "1", "party_id": "67890", - "call_id": "12345" + "call_id": "12345", + "reason": "user_hangup" } } diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index 051b3f1e1..eb682c69b 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -50,7 +50,6 @@ properties: - call_id - version - party_id - - reason type: type: string enum: From 1fda1ec52cc230608279fa5927cc8d1aef82970c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 09:43:49 +0100 Subject: [PATCH 22/38] Change tense Co-authored-by: Hubert Chathi --- content/client-server-api/modules/voip_events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index e269d640c..865004863 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -9,7 +9,7 @@ communication is supported (e.g. between two peers, or between a peer and a multi-point conferencing unit). This means that clients MUST only send call events to rooms with exactly two participants. -All VoIP events have a `version` field. This will be used to determine whether +All VoIP events have a `version` field. This is used to determine whether devices support this new version of the protocol. For example, clients can use this field to know whether to expect an `m.call.select_answer` event from their opponent. If clients see events with `version` other than `0` or `"1"` From a6c2cf25152cc047c778a21695083190bfa53a64 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 09:45:25 +0100 Subject: [PATCH 23/38] Tense, typos & grammar Co-authored-by: Hubert Chathi --- content/client-server-api/modules/voip_events.md | 8 ++++---- data/event-schemas/schema/m.call.negotiate.yaml | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index 865004863..98da7684d 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -30,7 +30,7 @@ lowercase alphanumeric characters is recommended. Parties in the call are identi The client adds a `party_id` field containing this ID to the top-level of the content of all VoIP events it sends on the call, including `m.call.invite`. Clients use this to identify remote echo of their own -events: since a user may now call themselves, they can no longer ignore events from their own user. This +events: since a user may call themselves, they cannot simply ignore events from their own user. This field also identifies different answers sent by different clients to an invite, and matches `m.call.candidates` events to their respective answer/invite. @@ -115,7 +115,7 @@ The same behaviour applies when a client is looking at historic calls. #### Supported Codecs The Matrix spec does not mandate particular audio or video codecs, but instead defers to the -WebRTC spec. A compliant matrix VoIP client will behave in the same way as a supported 'browser' +WebRTC spec. A compliant Matrix VoIP client will behave in the same way as a supported 'browser' in terms of what codecs it supports and what variants thereof. The latest WebRTC specification applies, so clients should keep up to date with new versions of the WebRTC specification whether or not there have been any changes to the Matrix spec. @@ -154,7 +154,7 @@ Or a rejected call: Calls are negotiated according to the WebRTC specification. -In response to an invoming invite, a client may do one of several things: +In response to an incoming invite, a client may do one of several things: * Attempt to accept the call by sending an `m.call.answer`. * Actively reject the call everywhere: send an `m.call.reject` as per above, which will stop the call from ringing on all the user's devices and the caller's client will inform them that the user has @@ -180,7 +180,7 @@ with respect to presenting such streams and tracks is undefined. ##### Invitees The `invitee` field should be added whenever the call is intended for one -specific user , and should be set to the Matrix user ID of that user. Invites +specific user, and should be set to the Matrix user ID of that user. Invites without an `invitee` field are defined to be intended for any member of the room other than the sender of the event. diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index 92aecef4b..272e3ef09 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -2,7 +2,7 @@ type: object description: | Provides SDP negotiation semantics for media pause, hold/resume, ICE restarts - and voice/video call up/downgrading. Clients should implement & honour hold + and voice/video call up/downgrading. Clients should implement and honour hold functionality as per WebRTC's recommendation: https://www.w3.org/TR/webrtc/#hold-functionality From ea3cbec3cb2c6396261c6098cd62dfd337ae53b5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 09:46:16 +0100 Subject: [PATCH 24/38] Linkify Co-authored-by: Hubert Chathi --- content/client-server-api/modules/voip_events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index 98da7684d..d9cdf90b6 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -42,7 +42,7 @@ send signalling for more than one call party. A grammar for `party_id` is defined [below](#grammar-for-voip-ids). #### Politeness -In line with WebRTC perfect negotiation (https://w3c.github.io/webrtc-pc/#perfect-negotiation-example) +In line with [WebRTC perfect negotiation](https://w3c.github.io/webrtc-pc/#perfect-negotiation-example) there are rules to establish which party is polite in the process of renegotiation. The callee is always the polite party. In a glare situation, the politenes of a party is therefore determined by whether the inbound or outbound call is used: if a client discards its outbound call in favour of From 70d7c36cd85407e3fe1d065e66c01a7ffd664e0c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 09:46:46 +0100 Subject: [PATCH 25/38] Remove unnecessary parts from link Co-authored-by: Hubert Chathi --- content/client-server-api/modules/voip_events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index d9cdf90b6..b929de6ae 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -102,7 +102,7 @@ of the characters `[0-9a-zA-Z._~-]`. (Note that this matches the grammar of 'opaque IDs' from [MSC1597](https://github.com/matrix-org/matrix-spec-proposals/blob/rav/proposals/id_grammar/proposals/1597-id-grammar.md#opaque-ids), and that of the `id` property of the - [`m.login.sso` flow schema](https://spec.matrix.org/v1.5/client-server-api/#definition-mloginsso-flow-schema).) + [`m.login.sso` flow schema](#definition-mloginsso-flow-schema).) #### Behaviour on Room Leave If the client sees the user it is in a call with leave the room, the client should treat this From 5b8e3ef92acad2fb7ba250cca7d4e09296e676ad Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 09:48:43 +0100 Subject: [PATCH 26/38] Capitalise Co-authored-by: Hubert Chathi --- content/client-server-api/modules/voip_events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index b929de6ae..b8ed2f2c6 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -170,7 +170,7 @@ voice call). They can optionally send a second track in the same stream of kind `video` (creating a video call). Clients implementing this specification use the first stream and will ignore -any streamless tracks. Note that in the Javascript WebRTC API, this means +any streamless tracks. Note that in the JavaScript WebRTC API, this means `addTrack()` must be passed two parameters: a track and a stream, not just a track, and in a video call the stream must be the same for both audio and video track. From 10233999972ee598a809e81347d410885aa4b35a Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 10:05:25 +0100 Subject: [PATCH 27/38] Fix hangup reasons --- data/event-schemas/schema/m.call.hangup.yaml | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index e9fba9003..72b20c75d 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -5,10 +5,11 @@ description: | be sent either once the call has has been established or before to abort the call. The meanings of the `reason` field are as follows: - * `ice_timeout`: The connection failed after some media was exchanged (as opposed to current - * `ice_failed` which means no media connection could be established). Note that, in the case of - an ICE renegotiation, a client should be sure to send `ice_timeout` rather than `ice_failed` if - media had previously been received successfully, even if the ICE renegotiation itself failed. + * `ice_failed`: ICE negotiation has failed and a media connection could not be established. + * `ice_timeout`: The connection failed after some media was exchanged (as opposed to `ice_failed` + which means no media connection could be established). Note that, in the case of an ICE + renegotiation, a client should be sure to send `ice_timeout` rather than `ice_failed` if media + had previously been received successfully, even if the ICE renegotiation itself failed. * `invite_timeout`: The other party did not answer in time. * `user_hangup`: Clients must now send this code when the user chooses to end the call, although for backwards compatibility with version 0, a clients should treat an absence of the `reason` From ea056a77be2b541e330b2be945502e4565cd3972 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 10:06:25 +0100 Subject: [PATCH 28/38] Clarify who can answer Co-authored-by: Hubert Chathi --- data/event-schemas/schema/m.call.invite.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index 7f8618bfa..d9f0b4420 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -43,7 +43,7 @@ }, "invitee": { "type": "string", - "description": "The ID of the user being called.", + "description": "The ID of the user being called. If omitted, any user in the room can answer.", } }, "required": ["call_id", "offer", "version", "lifetime", "party_id"] From 18552057c0090805f1d0d5a99284cec9e73d1c5e Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 10:06:46 +0100 Subject: [PATCH 29/38] Linkify Co-authored-by: Hubert Chathi --- data/event-schemas/schema/m.call.negotiate.yaml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index 272e3ef09..ca3e4d0db 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -3,8 +3,7 @@ type: object description: | Provides SDP negotiation semantics for media pause, hold/resume, ICE restarts and voice/video call up/downgrading. Clients should implement and honour hold - functionality as per WebRTC's recommendation: - https://www.w3.org/TR/webrtc/#hold-functionality + functionality as per [WebRTC's recommendation](https://www.w3.org/TR/webrtc/#hold-functionality). If both the invite event and the accepted answer event have `version` equal to `"1"`, either party may send `m.call.negotiate` with a `description` field From 25ea0df0d1ace1ac97ae69aefda6134d7fe42792 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 10:10:45 +0100 Subject: [PATCH 30/38] Remove reference to 'this MSC'. --- data/event-schemas/schema/m.call.negotiate.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index ca3e4d0db..83012966c 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -27,12 +27,12 @@ description: | another `m.call.negotiate` event, with the SDP answer (with `"type": "answer"`) in the `description` property. - This MSC also proposes clarifying the `m.call.invite` and `m.call.answer` - events to state that the `offer` and `answer` fields respectively are objects - of type `RTCSessionDescriptionInit`. Hence the `type` field, whilst - redundant in these events, is included for ease of working with the WebRTC - API and is mandatory. Receiving clients should not attempt to validate the - `type` field, but simply pass the object into the WebRTC API. + In the `m.call.invite` and `m.call.answer` events, the `offer` and `answer` + fields respectively are objects of type `RTCSessionDescriptionInit`. Hence + the `type` field, whilst redundant in these events, is included for ease of + working with the WebRTC API and is mandatory. Receiving clients should not + attempt to validate the `type` field, but simply pass the object into the + WebRTC API. allOf: - "$ref": core-event-schema/room_event.yaml properties: From 5d53d67efe2764426f7f4de7cd34441e7f217b4a Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 14:28:21 +0100 Subject: [PATCH 31/38] Move common VoIP fields into a call event type. --- .../client-server-api/modules/voip_events.md | 6 +++++ .../schema/core-event-schema/call_event.yaml | 26 +++++++++++++++++++ data/event-schemas/schema/m.call.answer.yaml | 16 ++---------- .../schema/m.call.candidates.yaml | 16 ++---------- data/event-schemas/schema/m.call.hangup.yaml | 20 +------------- data/event-schemas/schema/m.call.invite.yaml | 16 ++---------- .../schema/m.call.negotiate.yaml | 20 +------------- data/event-schemas/schema/m.call.reject.yaml | 21 ++------------- .../schema/m.call.select_answer.yaml | 16 ++---------- 9 files changed, 44 insertions(+), 113 deletions(-) create mode 100644 data/event-schemas/schema/core-event-schema/call_event.yaml diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index b8ed2f2c6..b15c42208 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -122,6 +122,12 @@ or not there have been any changes to the Matrix spec. #### Events +##### Common Fields + +{{% event-fields event_type="call_event" %}} + +##### Events + {{% event-group group_name="m.call" %}} #### Client behaviour diff --git a/data/event-schemas/schema/core-event-schema/call_event.yaml b/data/event-schemas/schema/core-event-schema/call_event.yaml new file mode 100644 index 000000000..4fcb833d1 --- /dev/null +++ b/data/event-schemas/schema/core-event-schema/call_event.yaml @@ -0,0 +1,26 @@ +allOf: +- "$ref": room_event.yaml + description: "All call events share a set of common fields: those of room events + and some additional VoIP specific fields." +properties: + call_id: + type: string + description: The ID of the call this event relates to. + version: + type: string + description: The version of the VoIP specification this message adheres to. + This specification is version 1. This field is a string such that experimental + implementations can use non-integer versions. This field was an integer + in the previous spec version and implementations must accept an integer + 0. + party_id: + type: string + description: 'This identifies the party that sent this event. A client may + choose to re-use the device ID from end-to-end cryptography for the value + of this field. ' +required: +- call_id +- version +- party_id +title: CallEvent +type: object diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index 7037f2543..58accd9d3 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -2,16 +2,12 @@ "type": "object", "description": "This event is sent by the callee when they wish to answer the call.", "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" + "$ref": "core-event-schema/call_event.yaml" }], "properties": { "content": { "type": "object", "properties": { - "call_id": { - "type": "string", - "description": "The ID of the call this event relates to." - }, "answer": { "type": "object", "title": "Answer", @@ -28,17 +24,9 @@ } }, "required": ["type", "sdp"] - }, - "version": { - "type": "string", - "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0" - }, - "party_id": { - "type": "string", - "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " } }, - "required": ["call_id", "answer", "version", "party_id"] + "required": ["answer"] }, "type": { "type": "string", diff --git a/data/event-schemas/schema/m.call.candidates.yaml b/data/event-schemas/schema/m.call.candidates.yaml index 8937fc1bd..4412dd1c9 100644 --- a/data/event-schemas/schema/m.call.candidates.yaml +++ b/data/event-schemas/schema/m.call.candidates.yaml @@ -2,16 +2,12 @@ "type": "object", "description": "This event is sent by callers after sending an invite and by the callee after answering. Its purpose is to give the other party additional ICE candidates to try using to communicate.", "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" + "$ref": "core-event-schema/call_event.yaml" }], "properties": { "content": { "type": "object", "properties": { - "call_id": { - "type": "string", - "description": "The ID of the call this event relates to." - }, "candidates": { "type": "array", "description": "Array of objects describing the candidates.", @@ -34,17 +30,9 @@ }, "required": ["candidate", "sdpMLineIndex", "sdpMid"] } - }, - "party_id": { - "type": "string", - "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " - }, - "version": { - "type": "string", - "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." } }, - "required": ["call_id", "candidates", "version", "party_id"] + "required": ["candidates"] }, "type": { "type": "string", diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 72b20c75d..25e7b153d 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -22,26 +22,11 @@ description: | * `unknown_error`: Some other failure occurred that meant the client was unable to continue the call rather than the user choosing to end it. allOf: -- "$ref": core-event-schema/room_event.yaml +- "$ref": core-event-schema/call_event.yaml properties: content: type: object properties: - call_id: - type: string - description: The ID of the call this event relates to. - version: - type: string - description: The version of the VoIP specification this message adheres to. - This specification is version 1. This field is a string such that experimental - implementations can use non-integer versions. This field was an integer - in the previous spec version and implementations must accept an integer - 0. - party_id: - type: string - description: This identifies the party that sent this event. A client may - choose to re-use the device ID from end-to-end cryptography for the value - of this field. reason: type: string description: Reason for the hangup. Note that this was optional in @@ -56,9 +41,6 @@ properties: - user_busy - unknown_error required: - - call_id - - version - - party_id - reason type: type: string diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index d9f0b4420..07dc5affd 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -2,16 +2,12 @@ "type": "object", "description": "This event is sent by the caller when they wish to establish a call.", "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" + "$ref": "core-event-schema/call_event.yaml" }], "properties": { "content": { "type": "object", "properties": { - "call_id": { - "type": "string", - "description": "A unique identifier for the call." - }, "offer": { "type": "object", "title": "Offer", @@ -29,14 +25,6 @@ }, "required": ["type", "sdp"] }, - "version": { - "type": "string", - "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." - }, - "party_id": { - "type": "string", - "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " - }, "lifetime": { "type": "integer", "description": "The time in milliseconds that the invite is valid for. Once the invite age exceeds this value, clients should discard it. They should also no longer show the call as awaiting an answer in the UI." @@ -46,7 +34,7 @@ "description": "The ID of the user being called. If omitted, any user in the room can answer.", } }, - "required": ["call_id", "offer", "version", "lifetime", "party_id"] + "required": ["offer", "lifetime"] }, "type": { "type": "string", diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index 83012966c..14efcbe29 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -34,26 +34,11 @@ description: | attempt to validate the `type` field, but simply pass the object into the WebRTC API. allOf: -- "$ref": core-event-schema/room_event.yaml +- "$ref": core-event-schema/call_event.yaml properties: content: type: object properties: - call_id: - type: string - description: The ID of the call this event relates to. - version: - type: string - description: The version of the VoIP specification this message adheres to. - This specification is version 1. This field is a string such that experimental - implementations can use non-integer versions. This field was an integer - in the previous spec version and implementations must accept an integer - 0. - party_id: - type: string - description: This identifies the party that sent this event. A client may - choose to re-use the device ID from end-to-end cryptography for the value - of this field. offer: type: object title: Offer @@ -77,9 +62,6 @@ properties: They should also no longer show the call as awaiting an answer in the UI. required: - - call_id - - version - - party_id - offer - lifetime type: diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index eb682c69b..bd745132f 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -13,26 +13,11 @@ description: | The meanings of the `reason` codes are the same as in [`m.call.hangup`](#mcallhangup). allOf: -- "$ref": core-event-schema/room_event.yaml +- "$ref": core-event-schema/call_event.yaml properties: content: type: object properties: - call_id: - type: string - description: The ID of the call this event relates to. - version: - type: string - description: The version of the VoIP specification this message adheres to. - This specification is version 1. This field is a string such that experimental - implementations can use non-integer versions. This field was an integer - in the previous spec version and implementations must accept an integer - 0. - party_id: - type: string - description: 'This identifies the party that sent this event. A client may - choose to re-use the device ID from end-to-end cryptography for the value - of this field. ' reason: type: string description: Reason for the hangup. Note that this was optional in @@ -47,9 +32,7 @@ properties: - user_busy - unknown_error required: - - call_id - - version - - party_id + - reason type: type: string enum: diff --git a/data/event-schemas/schema/m.call.select_answer.yaml b/data/event-schemas/schema/m.call.select_answer.yaml index a28a74650..8a9b68774 100644 --- a/data/event-schemas/schema/m.call.select_answer.yaml +++ b/data/event-schemas/schema/m.call.select_answer.yaml @@ -2,30 +2,18 @@ "type": "object", "description": "This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.", "allOf": [{ - "$ref": "core-event-schema/room_event.yaml" + "$ref": "core-event-schema/call_event.yaml" }], "properties": { "content": { "type": "object", "properties": { - "call_id": { - "type": "string", - "description": "The ID of the call this event relates to." - }, - "version": { - "type": "string", - "description": "The version of the VoIP specification this message adheres to. This specification is version 1. This field is a string such that experimental implementations can use non-integer versions. This field was an integer in the previous spec version and implementations must accept an integer 0." - }, - "party_id": { - "type": "string", - "description": "This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field. " - }, "selected_party_id": { "type": "string", "description": "The `party_id` field from the answer event that the caller chose." }, }, - "required": ["call_id", "version"] + "required": ["selected_party_id"] }, "type": { "type": "string", From ffa0a6f13b1b87b02c1712261c8dcf2841fb735b Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 14:43:18 +0100 Subject: [PATCH 32/38] Move common voip events to the content, not the actual event --- .../schema/core-event-schema/call_event.yaml | 8 +++----- data/event-schemas/schema/m.call.answer.yaml | 5 ++++- data/event-schemas/schema/m.call.candidates.yaml | 5 ++++- data/event-schemas/schema/m.call.hangup.yaml | 4 +++- data/event-schemas/schema/m.call.invite.yaml | 5 ++++- data/event-schemas/schema/m.call.negotiate.yaml | 4 +++- data/event-schemas/schema/m.call.reject.yaml | 4 +++- data/event-schemas/schema/m.call.select_answer.yaml | 5 ++++- 8 files changed, 28 insertions(+), 12 deletions(-) diff --git a/data/event-schemas/schema/core-event-schema/call_event.yaml b/data/event-schemas/schema/core-event-schema/call_event.yaml index 4fcb833d1..c089e0ad1 100644 --- a/data/event-schemas/schema/core-event-schema/call_event.yaml +++ b/data/event-schemas/schema/core-event-schema/call_event.yaml @@ -1,7 +1,5 @@ -allOf: -- "$ref": room_event.yaml - description: "All call events share a set of common fields: those of room events - and some additional VoIP specific fields." +description: "The content of all call events shares a set of common fields: those + of room events and some additional VoIP specific fields." properties: call_id: type: string @@ -17,7 +15,7 @@ properties: type: string description: 'This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value - of this field. ' + of this field.' required: - call_id - version diff --git a/data/event-schemas/schema/m.call.answer.yaml b/data/event-schemas/schema/m.call.answer.yaml index 58accd9d3..163690be2 100644 --- a/data/event-schemas/schema/m.call.answer.yaml +++ b/data/event-schemas/schema/m.call.answer.yaml @@ -2,11 +2,14 @@ "type": "object", "description": "This event is sent by the callee when they wish to answer the call.", "allOf": [{ - "$ref": "core-event-schema/call_event.yaml" + "$ref": "core-event-schema/room_event.yaml" }], "properties": { "content": { "type": "object", + "allOf": [{ + "$ref": "core-event-schema/call_event.yaml" + }], "properties": { "answer": { "type": "object", diff --git a/data/event-schemas/schema/m.call.candidates.yaml b/data/event-schemas/schema/m.call.candidates.yaml index 4412dd1c9..6aa162296 100644 --- a/data/event-schemas/schema/m.call.candidates.yaml +++ b/data/event-schemas/schema/m.call.candidates.yaml @@ -2,11 +2,14 @@ "type": "object", "description": "This event is sent by callers after sending an invite and by the callee after answering. Its purpose is to give the other party additional ICE candidates to try using to communicate.", "allOf": [{ - "$ref": "core-event-schema/call_event.yaml" + "$ref": "core-event-schema/room_event.yaml" }], "properties": { "content": { "type": "object", + "allOf": [{ + "$ref": "core-event-schema/call_event.yaml" + }], "properties": { "candidates": { "type": "array", diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 25e7b153d..480ce419e 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -22,10 +22,12 @@ description: | * `unknown_error`: Some other failure occurred that meant the client was unable to continue the call rather than the user choosing to end it. allOf: -- "$ref": core-event-schema/call_event.yaml +- "$ref": core-event-schema/room_event.yaml properties: content: type: object + allOf: + - "$ref": core-event-schema/call_event.yaml properties: reason: type: string diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index 07dc5affd..5ab1cee4a 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -2,11 +2,14 @@ "type": "object", "description": "This event is sent by the caller when they wish to establish a call.", "allOf": [{ - "$ref": "core-event-schema/call_event.yaml" + "$ref": "core-event-schema/room_event.yaml" }], "properties": { "content": { "type": "object", + "allOf": [{ + "$ref": "core-event-schema/call_event.yaml" + }], "properties": { "offer": { "type": "object", diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index 14efcbe29..631ac238c 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -34,10 +34,12 @@ description: | attempt to validate the `type` field, but simply pass the object into the WebRTC API. allOf: -- "$ref": core-event-schema/call_event.yaml +- "$ref": core-event-schema/room_event.yaml properties: content: type: object + allOf: + - "$ref": core-event-schema/call_event.yaml properties: offer: type: object diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index bd745132f..695cabbf6 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -13,10 +13,12 @@ description: | The meanings of the `reason` codes are the same as in [`m.call.hangup`](#mcallhangup). allOf: -- "$ref": core-event-schema/call_event.yaml +- "$ref": core-event-schema/room_event.yaml properties: content: type: object + allOf: + - "$ref": core-event-schema/call_event.yaml properties: reason: type: string diff --git a/data/event-schemas/schema/m.call.select_answer.yaml b/data/event-schemas/schema/m.call.select_answer.yaml index 8a9b68774..774d02eaa 100644 --- a/data/event-schemas/schema/m.call.select_answer.yaml +++ b/data/event-schemas/schema/m.call.select_answer.yaml @@ -2,11 +2,14 @@ "type": "object", "description": "This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.", "allOf": [{ - "$ref": "core-event-schema/call_event.yaml" + "$ref": "core-event-schema/room_event.yaml" }], "properties": { "content": { "type": "object", + "allOf": [{ + "$ref": "core-event-schema/call_event.yaml" + }], "properties": { "selected_party_id": { "type": "string", From a5c9911f60f3d9f337f7daca0fd012ea6e001745 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 14:51:50 +0100 Subject: [PATCH 33/38] Remove reason from reject event I confused myself, but it's not in the MSC and it shouldn't be. --- data/event-schemas/schema/m.call.reject.yaml | 19 ++----------------- 1 file changed, 2 insertions(+), 17 deletions(-) diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index 695cabbf6..ee4d0b1da 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -11,7 +11,8 @@ description: | the callee sends an `m.call.hangup` event. If the calling user chooses to end the call before setup is complete, the client sends `m.call.hangup` as previously. - The meanings of the `reason` codes are the same as in [`m.call.hangup`](#mcallhangup). +Note that, unlike `m.call.hangup`, this event has no `reason` field: the rejection of +a call is always implicitly because the user chose not to answer it. allOf: - "$ref": core-event-schema/room_event.yaml properties: @@ -19,22 +20,6 @@ properties: type: object allOf: - "$ref": core-event-schema/call_event.yaml - properties: - reason: - type: string - description: Reason for the hangup. Note that this was optional in - previous previous versions of the spec, so a missing value should be - treated as `user_hangup`. - enum: - - ice_timeout - - ice_failed - - invite_timeout - - user_hangup - - user_media_failed - - user_busy - - unknown_error - required: - - reason type: type: string enum: From d1b4c72762c4ba0da05c9408c9eba52295a448d3 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 17 May 2023 14:53:24 +0100 Subject: [PATCH 34/38] Failure to YAML --- data/event-schemas/schema/m.call.reject.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index ee4d0b1da..6793219c9 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -11,8 +11,8 @@ description: | the callee sends an `m.call.hangup` event. If the calling user chooses to end the call before setup is complete, the client sends `m.call.hangup` as previously. -Note that, unlike `m.call.hangup`, this event has no `reason` field: the rejection of -a call is always implicitly because the user chose not to answer it. + Note that, unlike `m.call.hangup`, this event has no `reason` field: the rejection of + a call is always implicitly because the user chose not to answer it. allOf: - "$ref": core-event-schema/room_event.yaml properties: From 163605c4f1a7dd22bf536d5bbe90f8e67c943e15 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 23 May 2023 13:33:22 -0400 Subject: [PATCH 35/38] Fix number of room members allowed when sending voip events. Co-authored-by: Hubert Chathi --- content/client-server-api/modules/voip_events.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/content/client-server-api/modules/voip_events.md b/content/client-server-api/modules/voip_events.md index b15c42208..75cc7757b 100644 --- a/content/client-server-api/modules/voip_events.md +++ b/content/client-server-api/modules/voip_events.md @@ -6,8 +6,8 @@ This module outlines how two users in a room can set up a Voice over IP WebRTC 1.0 standard. Call signalling is achieved by sending [message events](#events) to the room. In this version of the spec, only two-party communication is supported (e.g. between two peers, or between a peer -and a multi-point conferencing unit). This means that clients MUST only -send call events to rooms with exactly two participants. +and a multi-point conferencing unit). Calls can take place in rooms with +multiple members, but only two devices can take part in the call. All VoIP events have a `version` field. This is used to determine whether devices support this new version of the protocol. For example, clients can use From c6ae1a4c98152a6c176e3f0979e3287555db7018 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 23 May 2023 13:34:14 -0400 Subject: [PATCH 36/38] Add 'added in' version Co-authored-by: Hubert Chathi --- data/event-schemas/schema/core-event-schema/call_event.yaml | 1 + data/event-schemas/schema/m.call.hangup.yaml | 3 +++ data/event-schemas/schema/m.call.invite.yaml | 1 + data/event-schemas/schema/m.call.negotiate.yaml | 1 + data/event-schemas/schema/m.call.reject.yaml | 1 + 5 files changed, 7 insertions(+) diff --git a/data/event-schemas/schema/core-event-schema/call_event.yaml b/data/event-schemas/schema/core-event-schema/call_event.yaml index c089e0ad1..a8175fc84 100644 --- a/data/event-schemas/schema/core-event-schema/call_event.yaml +++ b/data/event-schemas/schema/core-event-schema/call_event.yaml @@ -16,6 +16,7 @@ properties: description: 'This identifies the party that sent this event. A client may choose to re-use the device ID from end-to-end cryptography for the value of this field.' + x-addedInMatrixVersion: "1.7" required: - call_id - version diff --git a/data/event-schemas/schema/m.call.hangup.yaml b/data/event-schemas/schema/m.call.hangup.yaml index 480ce419e..65d697ab1 100644 --- a/data/event-schemas/schema/m.call.hangup.yaml +++ b/data/event-schemas/schema/m.call.hangup.yaml @@ -34,6 +34,9 @@ properties: description: Reason for the hangup. Note that this was optional in previous previous versions of the spec, so a missing value should be treated as `user_hangup`. + x-changedInMatrixVersion: + 1.7: |- + Additional values were added. enum: - ice_timeout - ice_failed diff --git a/data/event-schemas/schema/m.call.invite.yaml b/data/event-schemas/schema/m.call.invite.yaml index 5ab1cee4a..72020b266 100644 --- a/data/event-schemas/schema/m.call.invite.yaml +++ b/data/event-schemas/schema/m.call.invite.yaml @@ -35,6 +35,7 @@ "invitee": { "type": "string", "description": "The ID of the user being called. If omitted, any user in the room can answer.", + "x-addedInMatrixVersion": "1.7", } }, "required": ["offer", "lifetime"] diff --git a/data/event-schemas/schema/m.call.negotiate.yaml b/data/event-schemas/schema/m.call.negotiate.yaml index 631ac238c..abc5ef1d8 100644 --- a/data/event-schemas/schema/m.call.negotiate.yaml +++ b/data/event-schemas/schema/m.call.negotiate.yaml @@ -33,6 +33,7 @@ description: | working with the WebRTC API and is mandatory. Receiving clients should not attempt to validate the `type` field, but simply pass the object into the WebRTC API. +x-addedInMatrixVersion: "1.7" allOf: - "$ref": core-event-schema/room_event.yaml properties: diff --git a/data/event-schemas/schema/m.call.reject.yaml b/data/event-schemas/schema/m.call.reject.yaml index 6793219c9..39726c1a7 100644 --- a/data/event-schemas/schema/m.call.reject.yaml +++ b/data/event-schemas/schema/m.call.reject.yaml @@ -13,6 +13,7 @@ description: | Note that, unlike `m.call.hangup`, this event has no `reason` field: the rejection of a call is always implicitly because the user chose not to answer it. +x-addedInMatrixVersion: "1.7" allOf: - "$ref": core-event-schema/room_event.yaml properties: From d230788278b0b76f3050dd5b2fceac2139ce6246 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 23 May 2023 13:56:07 -0400 Subject: [PATCH 37/38] Another added-in Co-authored-by: Hubert Chathi --- data/event-schemas/schema/m.call.select_answer.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/data/event-schemas/schema/m.call.select_answer.yaml b/data/event-schemas/schema/m.call.select_answer.yaml index 774d02eaa..89cc7fc6d 100644 --- a/data/event-schemas/schema/m.call.select_answer.yaml +++ b/data/event-schemas/schema/m.call.select_answer.yaml @@ -1,6 +1,7 @@ { "type": "object", "description": "This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.", + "x-addedInMatrixVersion": "1.7" "allOf": [{ "$ref": "core-event-schema/room_event.yaml" }], From 492d0523b8d59d01a57caed983a66c7e9cb2d040 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Tue, 23 May 2023 12:05:15 -0600 Subject: [PATCH 38/38] Add missing comma --- data/event-schemas/schema/m.call.select_answer.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/event-schemas/schema/m.call.select_answer.yaml b/data/event-schemas/schema/m.call.select_answer.yaml index 89cc7fc6d..b47c1352b 100644 --- a/data/event-schemas/schema/m.call.select_answer.yaml +++ b/data/event-schemas/schema/m.call.select_answer.yaml @@ -1,7 +1,7 @@ { "type": "object", "description": "This event is sent by the caller's client once it has decided which other client to talk to, by selecting one of multiple possible incoming `m.call.answer` events. Its `selected_party_id` field indicates the answer it's chosen. The `call_id` and `party_id` of the caller is also included. If the callee's client sees a `select_answer` for an answer with party ID other than the one it sent, it ends the call and informs the user the call was answered elsewhere. It does not send any events. Media can start flowing before this event is seen or even sent. Clients that implement previous versions of this specification will ignore this event and behave as they did before.", - "x-addedInMatrixVersion": "1.7" + "x-addedInMatrixVersion": "1.7", "allOf": [{ "$ref": "core-event-schema/room_event.yaml" }],