Merge branch 'master' into travis/msc/global-versioning
This commit is contained in:
commit
8d6642aaa7
29 changed files with 898 additions and 91 deletions
|
@ -13,7 +13,7 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
swagger: '2.0'
|
swagger: '2.0'
|
||||||
info:
|
info:
|
||||||
title: "Matrix Client-Server Capabiltiies API"
|
title: "Matrix Client-Server Capabilities API"
|
||||||
version: "1.0.0"
|
version: "1.0.0"
|
||||||
host: localhost:8008
|
host: localhost:8008
|
||||||
schemes:
|
schemes:
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
1
changelogs/client_server/newsfragments/2399.feature
Normal file
1
changelogs/client_server/newsfragments/2399.feature
Normal file
|
@ -0,0 +1 @@
|
||||||
|
Document how clients can advise recipients that it is withholding decryption keys as per `MSC2399 <https://github.com/matrix-org/matrix-doc/pull/2399>`_.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
|
@ -0,0 +1 @@
|
||||||
|
Fix various typos throughout the specification.
|
66
data-definitions/sas-emoji-v1-i18n/bg.json
Normal file
66
data-definitions/sas-emoji-v1-i18n/bg.json
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"Pin": "Кабърче",
|
||||||
|
"Folder": "Папка",
|
||||||
|
"Headphones": "Слушалки",
|
||||||
|
"Anchor": "Котва",
|
||||||
|
"Bell": "Звънец",
|
||||||
|
"Trumpet": "Тромпет",
|
||||||
|
"Guitar": "Китара",
|
||||||
|
"Ball": "Топка",
|
||||||
|
"Trophy": "Трофей",
|
||||||
|
"Rocket": "Ракета",
|
||||||
|
"Aeroplane": "Самолет",
|
||||||
|
"Bicycle": "Колело",
|
||||||
|
"Train": "Влак",
|
||||||
|
"Flag": "Флаг",
|
||||||
|
"Telephone": "Телефон",
|
||||||
|
"Hammer": "Чук",
|
||||||
|
"Key": "Ключ",
|
||||||
|
"Lock": "Катинар",
|
||||||
|
"Scissors": "Ножици",
|
||||||
|
"Paperclip": "Кламер",
|
||||||
|
"Pencil": "Молив",
|
||||||
|
"Book": "Книга",
|
||||||
|
"Light Bulb": "Лампа",
|
||||||
|
"Gift": "Подарък",
|
||||||
|
"Clock": "Часовник",
|
||||||
|
"Hourglass": "Пясъчен часовник",
|
||||||
|
"Umbrella": "Чадър",
|
||||||
|
"Thumbs Up": "Палец нагоре",
|
||||||
|
"Santa": "Дядо Коледа",
|
||||||
|
"Spanner": "Гаечен ключ",
|
||||||
|
"Glasses": "Очила",
|
||||||
|
"Hat": "Шапка",
|
||||||
|
"Robot": "Робот",
|
||||||
|
"Smiley": "Усмивка",
|
||||||
|
"Heart": "Сърце",
|
||||||
|
"Cake": "Торта",
|
||||||
|
"Pizza": "Пица",
|
||||||
|
"Corn": "Царевица",
|
||||||
|
"Strawberry": "Ягода",
|
||||||
|
"Apple": "Ябълка",
|
||||||
|
"Banana": "Банан",
|
||||||
|
"Fire": "Огън",
|
||||||
|
"Cloud": "Облак",
|
||||||
|
"Moon": "Луна",
|
||||||
|
"Globe": "Глобус",
|
||||||
|
"Mushroom": "Гъба",
|
||||||
|
"Cactus": "Кактус",
|
||||||
|
"Tree": "Дърво",
|
||||||
|
"Flower": "Цвете",
|
||||||
|
"Butterfly": "Пеперуда",
|
||||||
|
"Octopus": "Октопод",
|
||||||
|
"Fish": "Риба",
|
||||||
|
"Turtle": "Костенурка",
|
||||||
|
"Penguin": "Пингвин",
|
||||||
|
"Rooster": "Петел",
|
||||||
|
"Panda": "Панда",
|
||||||
|
"Rabbit": "Заек",
|
||||||
|
"Elephant": "Слон",
|
||||||
|
"Pig": "Прасе",
|
||||||
|
"Unicorn": "Еднорог",
|
||||||
|
"Horse": "Кон",
|
||||||
|
"Lion": "Лъв",
|
||||||
|
"Cat": "Котка",
|
||||||
|
"Dog": "Куче"
|
||||||
|
}
|
66
data-definitions/sas-emoji-v1-i18n/ca.json
Normal file
66
data-definitions/sas-emoji-v1-i18n/ca.json
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
{
|
||||||
|
"Cactus": "Cactus",
|
||||||
|
"Globe": "Globus terraqüi",
|
||||||
|
"Rooster": "Gall",
|
||||||
|
"Pin": "Xinxeta",
|
||||||
|
"Folder": "Carpeta",
|
||||||
|
"Headphones": "Auriculars",
|
||||||
|
"Anchor": "Àncora",
|
||||||
|
"Bell": "Campana",
|
||||||
|
"Trumpet": "Trompeta",
|
||||||
|
"Guitar": "Guitarra",
|
||||||
|
"Ball": "Pilota",
|
||||||
|
"Trophy": "Trofeu",
|
||||||
|
"Rocket": "Coet",
|
||||||
|
"Aeroplane": "Avió",
|
||||||
|
"Bicycle": "Bicicleta",
|
||||||
|
"Train": "Tren",
|
||||||
|
"Flag": "Bandera",
|
||||||
|
"Telephone": "Telèfon",
|
||||||
|
"Hammer": "Martell",
|
||||||
|
"Lock": "Cadenat",
|
||||||
|
"Key": "Clau",
|
||||||
|
"Scissors": "Tisores",
|
||||||
|
"Paperclip": "Clip",
|
||||||
|
"Pencil": "Llapis",
|
||||||
|
"Book": "Llibre",
|
||||||
|
"Light Bulb": "Bombeta",
|
||||||
|
"Gift": "Regal",
|
||||||
|
"Clock": "Rellotge",
|
||||||
|
"Hourglass": "Rellotge de sorra",
|
||||||
|
"Umbrella": "Paraigües",
|
||||||
|
"Thumbs Up": "Polzes amunt",
|
||||||
|
"Santa": "Pare Noél",
|
||||||
|
"Spanner": "Clau anglesa",
|
||||||
|
"Glasses": "Ulleres",
|
||||||
|
"Hat": "Barret",
|
||||||
|
"Robot": "Robot",
|
||||||
|
"Smiley": "Somrient",
|
||||||
|
"Heart": "Cor",
|
||||||
|
"Cake": "Pastís",
|
||||||
|
"Pizza": "Pizza",
|
||||||
|
"Corn": "Blat de moro",
|
||||||
|
"Strawberry": "Maduixa",
|
||||||
|
"Apple": "Poma",
|
||||||
|
"Banana": "Plàtan",
|
||||||
|
"Fire": "Foc",
|
||||||
|
"Cloud": "Núvol",
|
||||||
|
"Moon": "Lluna",
|
||||||
|
"Mushroom": "Bolet",
|
||||||
|
"Tree": "Arbre",
|
||||||
|
"Flower": "Flor",
|
||||||
|
"Butterfly": "Papallona",
|
||||||
|
"Octopus": "Pop",
|
||||||
|
"Fish": "Peix",
|
||||||
|
"Turtle": "Tortuga",
|
||||||
|
"Penguin": "Pingüí",
|
||||||
|
"Panda": "Panda",
|
||||||
|
"Rabbit": "Conill",
|
||||||
|
"Elephant": "Elefant",
|
||||||
|
"Unicorn": "Unicorn",
|
||||||
|
"Pig": "Porc",
|
||||||
|
"Horse": "Cavall",
|
||||||
|
"Lion": "Lleó",
|
||||||
|
"Cat": "Gat",
|
||||||
|
"Dog": "Gos"
|
||||||
|
}
|
|
@ -5,6 +5,8 @@
|
||||||
"description": "Dog",
|
"description": "Dog",
|
||||||
"unicode": "U+1F436",
|
"unicode": "U+1F436",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Куче",
|
||||||
|
"ca": "Gos",
|
||||||
"de": "Hund",
|
"de": "Hund",
|
||||||
"eo": "Hundo",
|
"eo": "Hundo",
|
||||||
"es": "Perro",
|
"es": "Perro",
|
||||||
|
@ -29,6 +31,8 @@
|
||||||
"description": "Cat",
|
"description": "Cat",
|
||||||
"unicode": "U+1F431",
|
"unicode": "U+1F431",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Котка",
|
||||||
|
"ca": "Gat",
|
||||||
"de": "Katze",
|
"de": "Katze",
|
||||||
"eo": "Kato",
|
"eo": "Kato",
|
||||||
"es": "Gato",
|
"es": "Gato",
|
||||||
|
@ -53,6 +57,8 @@
|
||||||
"description": "Lion",
|
"description": "Lion",
|
||||||
"unicode": "U+1F981",
|
"unicode": "U+1F981",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Лъв",
|
||||||
|
"ca": "Lleó",
|
||||||
"de": "Löwe",
|
"de": "Löwe",
|
||||||
"eo": "Leono",
|
"eo": "Leono",
|
||||||
"es": "León",
|
"es": "León",
|
||||||
|
@ -77,6 +83,8 @@
|
||||||
"description": "Horse",
|
"description": "Horse",
|
||||||
"unicode": "U+1F40E",
|
"unicode": "U+1F40E",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Кон",
|
||||||
|
"ca": "Cavall",
|
||||||
"de": "Pferd",
|
"de": "Pferd",
|
||||||
"eo": "Ĉevalo",
|
"eo": "Ĉevalo",
|
||||||
"es": "Caballo",
|
"es": "Caballo",
|
||||||
|
@ -101,6 +109,8 @@
|
||||||
"description": "Unicorn",
|
"description": "Unicorn",
|
||||||
"unicode": "U+1F984",
|
"unicode": "U+1F984",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Еднорог",
|
||||||
|
"ca": "Unicorn",
|
||||||
"de": "Einhorn",
|
"de": "Einhorn",
|
||||||
"eo": "Unukorno",
|
"eo": "Unukorno",
|
||||||
"es": "Unicornio",
|
"es": "Unicornio",
|
||||||
|
@ -125,6 +135,8 @@
|
||||||
"description": "Pig",
|
"description": "Pig",
|
||||||
"unicode": "U+1F437",
|
"unicode": "U+1F437",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Прасе",
|
||||||
|
"ca": "Porc",
|
||||||
"de": "Schwein",
|
"de": "Schwein",
|
||||||
"eo": "Porko",
|
"eo": "Porko",
|
||||||
"es": "Cerdo",
|
"es": "Cerdo",
|
||||||
|
@ -149,6 +161,8 @@
|
||||||
"description": "Elephant",
|
"description": "Elephant",
|
||||||
"unicode": "U+1F418",
|
"unicode": "U+1F418",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Слон",
|
||||||
|
"ca": "Elefant",
|
||||||
"de": "Elefant",
|
"de": "Elefant",
|
||||||
"eo": "Elefanto",
|
"eo": "Elefanto",
|
||||||
"es": "Elefante",
|
"es": "Elefante",
|
||||||
|
@ -173,6 +187,8 @@
|
||||||
"description": "Rabbit",
|
"description": "Rabbit",
|
||||||
"unicode": "U+1F430",
|
"unicode": "U+1F430",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Заек",
|
||||||
|
"ca": "Conill",
|
||||||
"de": "Hase",
|
"de": "Hase",
|
||||||
"eo": "Kuniklo",
|
"eo": "Kuniklo",
|
||||||
"es": "Conejo",
|
"es": "Conejo",
|
||||||
|
@ -197,6 +213,8 @@
|
||||||
"description": "Panda",
|
"description": "Panda",
|
||||||
"unicode": "U+1F43C",
|
"unicode": "U+1F43C",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Панда",
|
||||||
|
"ca": "Panda",
|
||||||
"de": "Panda",
|
"de": "Panda",
|
||||||
"eo": "Pando",
|
"eo": "Pando",
|
||||||
"es": "Panda",
|
"es": "Panda",
|
||||||
|
@ -221,6 +239,8 @@
|
||||||
"description": "Rooster",
|
"description": "Rooster",
|
||||||
"unicode": "U+1F413",
|
"unicode": "U+1F413",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Петел",
|
||||||
|
"ca": "Gall",
|
||||||
"de": "Hahn",
|
"de": "Hahn",
|
||||||
"eo": "Virkoko",
|
"eo": "Virkoko",
|
||||||
"es": "Gallo",
|
"es": "Gallo",
|
||||||
|
@ -245,6 +265,8 @@
|
||||||
"description": "Penguin",
|
"description": "Penguin",
|
||||||
"unicode": "U+1F427",
|
"unicode": "U+1F427",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Пингвин",
|
||||||
|
"ca": "Pingüí",
|
||||||
"de": "Pinguin",
|
"de": "Pinguin",
|
||||||
"eo": "Pingveno",
|
"eo": "Pingveno",
|
||||||
"es": "Pingüino",
|
"es": "Pingüino",
|
||||||
|
@ -269,6 +291,8 @@
|
||||||
"description": "Turtle",
|
"description": "Turtle",
|
||||||
"unicode": "U+1F422",
|
"unicode": "U+1F422",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Костенурка",
|
||||||
|
"ca": "Tortuga",
|
||||||
"de": "Schildkröte",
|
"de": "Schildkröte",
|
||||||
"eo": "Testudo",
|
"eo": "Testudo",
|
||||||
"es": "Tortuga",
|
"es": "Tortuga",
|
||||||
|
@ -293,6 +317,8 @@
|
||||||
"description": "Fish",
|
"description": "Fish",
|
||||||
"unicode": "U+1F41F",
|
"unicode": "U+1F41F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Риба",
|
||||||
|
"ca": "Peix",
|
||||||
"de": "Fisch",
|
"de": "Fisch",
|
||||||
"eo": "Fiŝo",
|
"eo": "Fiŝo",
|
||||||
"es": "Pez",
|
"es": "Pez",
|
||||||
|
@ -317,6 +343,8 @@
|
||||||
"description": "Octopus",
|
"description": "Octopus",
|
||||||
"unicode": "U+1F419",
|
"unicode": "U+1F419",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Октопод",
|
||||||
|
"ca": "Pop",
|
||||||
"de": "Oktopus",
|
"de": "Oktopus",
|
||||||
"eo": "Polpo",
|
"eo": "Polpo",
|
||||||
"es": "Pulpo",
|
"es": "Pulpo",
|
||||||
|
@ -341,6 +369,8 @@
|
||||||
"description": "Butterfly",
|
"description": "Butterfly",
|
||||||
"unicode": "U+1F98B",
|
"unicode": "U+1F98B",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Пеперуда",
|
||||||
|
"ca": "Papallona",
|
||||||
"de": "Schmetterling",
|
"de": "Schmetterling",
|
||||||
"eo": "Papilio",
|
"eo": "Papilio",
|
||||||
"es": "Mariposa",
|
"es": "Mariposa",
|
||||||
|
@ -365,6 +395,8 @@
|
||||||
"description": "Flower",
|
"description": "Flower",
|
||||||
"unicode": "U+1F337",
|
"unicode": "U+1F337",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Цвете",
|
||||||
|
"ca": "Flor",
|
||||||
"de": "Blume",
|
"de": "Blume",
|
||||||
"eo": "Floro",
|
"eo": "Floro",
|
||||||
"es": "Flor",
|
"es": "Flor",
|
||||||
|
@ -389,6 +421,8 @@
|
||||||
"description": "Tree",
|
"description": "Tree",
|
||||||
"unicode": "U+1F333",
|
"unicode": "U+1F333",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Дърво",
|
||||||
|
"ca": "Arbre",
|
||||||
"de": "Baum",
|
"de": "Baum",
|
||||||
"eo": "Arbo",
|
"eo": "Arbo",
|
||||||
"es": "Árbol",
|
"es": "Árbol",
|
||||||
|
@ -413,6 +447,8 @@
|
||||||
"description": "Cactus",
|
"description": "Cactus",
|
||||||
"unicode": "U+1F335",
|
"unicode": "U+1F335",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Кактус",
|
||||||
|
"ca": "Cactus",
|
||||||
"de": "Kaktus",
|
"de": "Kaktus",
|
||||||
"eo": "Kakto",
|
"eo": "Kakto",
|
||||||
"es": "Cactus",
|
"es": "Cactus",
|
||||||
|
@ -437,6 +473,8 @@
|
||||||
"description": "Mushroom",
|
"description": "Mushroom",
|
||||||
"unicode": "U+1F344",
|
"unicode": "U+1F344",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Гъба",
|
||||||
|
"ca": "Bolet",
|
||||||
"de": "Pilz",
|
"de": "Pilz",
|
||||||
"eo": "Fungo",
|
"eo": "Fungo",
|
||||||
"es": "Seta",
|
"es": "Seta",
|
||||||
|
@ -461,6 +499,8 @@
|
||||||
"description": "Globe",
|
"description": "Globe",
|
||||||
"unicode": "U+1F30F",
|
"unicode": "U+1F30F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Глобус",
|
||||||
|
"ca": "Globus terraqüi",
|
||||||
"de": "Globus",
|
"de": "Globus",
|
||||||
"eo": "Globo",
|
"eo": "Globo",
|
||||||
"es": "Globo",
|
"es": "Globo",
|
||||||
|
@ -485,6 +525,8 @@
|
||||||
"description": "Moon",
|
"description": "Moon",
|
||||||
"unicode": "U+1F319",
|
"unicode": "U+1F319",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Луна",
|
||||||
|
"ca": "Lluna",
|
||||||
"de": "Mond",
|
"de": "Mond",
|
||||||
"eo": "Luno",
|
"eo": "Luno",
|
||||||
"es": "Luna",
|
"es": "Luna",
|
||||||
|
@ -509,6 +551,8 @@
|
||||||
"description": "Cloud",
|
"description": "Cloud",
|
||||||
"unicode": "U+2601U+FE0F",
|
"unicode": "U+2601U+FE0F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Облак",
|
||||||
|
"ca": "Núvol",
|
||||||
"de": "Wolke",
|
"de": "Wolke",
|
||||||
"eo": "Nubo",
|
"eo": "Nubo",
|
||||||
"es": "Nube",
|
"es": "Nube",
|
||||||
|
@ -533,6 +577,8 @@
|
||||||
"description": "Fire",
|
"description": "Fire",
|
||||||
"unicode": "U+1F525",
|
"unicode": "U+1F525",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Огън",
|
||||||
|
"ca": "Foc",
|
||||||
"de": "Feuer",
|
"de": "Feuer",
|
||||||
"eo": "Fajro",
|
"eo": "Fajro",
|
||||||
"es": "Fuego",
|
"es": "Fuego",
|
||||||
|
@ -557,6 +603,8 @@
|
||||||
"description": "Banana",
|
"description": "Banana",
|
||||||
"unicode": "U+1F34C",
|
"unicode": "U+1F34C",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Банан",
|
||||||
|
"ca": "Plàtan",
|
||||||
"de": "Banane",
|
"de": "Banane",
|
||||||
"eo": "Banano",
|
"eo": "Banano",
|
||||||
"es": "Plátano",
|
"es": "Plátano",
|
||||||
|
@ -581,6 +629,8 @@
|
||||||
"description": "Apple",
|
"description": "Apple",
|
||||||
"unicode": "U+1F34E",
|
"unicode": "U+1F34E",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Ябълка",
|
||||||
|
"ca": "Poma",
|
||||||
"de": "Apfel",
|
"de": "Apfel",
|
||||||
"eo": "Pomo",
|
"eo": "Pomo",
|
||||||
"es": "Manzana",
|
"es": "Manzana",
|
||||||
|
@ -605,6 +655,8 @@
|
||||||
"description": "Strawberry",
|
"description": "Strawberry",
|
||||||
"unicode": "U+1F353",
|
"unicode": "U+1F353",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Ягода",
|
||||||
|
"ca": "Maduixa",
|
||||||
"de": "Erdbeere",
|
"de": "Erdbeere",
|
||||||
"eo": "Frago",
|
"eo": "Frago",
|
||||||
"es": "Fresa",
|
"es": "Fresa",
|
||||||
|
@ -629,6 +681,8 @@
|
||||||
"description": "Corn",
|
"description": "Corn",
|
||||||
"unicode": "U+1F33D",
|
"unicode": "U+1F33D",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Царевица",
|
||||||
|
"ca": "Blat de moro",
|
||||||
"de": "Korn",
|
"de": "Korn",
|
||||||
"eo": "Maizo",
|
"eo": "Maizo",
|
||||||
"es": "Maíz",
|
"es": "Maíz",
|
||||||
|
@ -653,6 +707,8 @@
|
||||||
"description": "Pizza",
|
"description": "Pizza",
|
||||||
"unicode": "U+1F355",
|
"unicode": "U+1F355",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Пица",
|
||||||
|
"ca": "Pizza",
|
||||||
"de": "Pizza",
|
"de": "Pizza",
|
||||||
"eo": "Pico",
|
"eo": "Pico",
|
||||||
"es": "Pizza",
|
"es": "Pizza",
|
||||||
|
@ -677,6 +733,8 @@
|
||||||
"description": "Cake",
|
"description": "Cake",
|
||||||
"unicode": "U+1F382",
|
"unicode": "U+1F382",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Торта",
|
||||||
|
"ca": "Pastís",
|
||||||
"de": "Kuchen",
|
"de": "Kuchen",
|
||||||
"eo": "Torto",
|
"eo": "Torto",
|
||||||
"es": "Tarta",
|
"es": "Tarta",
|
||||||
|
@ -701,6 +759,8 @@
|
||||||
"description": "Heart",
|
"description": "Heart",
|
||||||
"unicode": "U+2764U+FE0F",
|
"unicode": "U+2764U+FE0F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Сърце",
|
||||||
|
"ca": "Cor",
|
||||||
"de": "Herz",
|
"de": "Herz",
|
||||||
"eo": "Koro",
|
"eo": "Koro",
|
||||||
"es": "Corazón",
|
"es": "Corazón",
|
||||||
|
@ -725,6 +785,8 @@
|
||||||
"description": "Smiley",
|
"description": "Smiley",
|
||||||
"unicode": "U+1F600",
|
"unicode": "U+1F600",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Усмивка",
|
||||||
|
"ca": "Somrient",
|
||||||
"de": "Smiley",
|
"de": "Smiley",
|
||||||
"eo": "Rideto",
|
"eo": "Rideto",
|
||||||
"es": "Emoticono",
|
"es": "Emoticono",
|
||||||
|
@ -749,6 +811,8 @@
|
||||||
"description": "Robot",
|
"description": "Robot",
|
||||||
"unicode": "U+1F916",
|
"unicode": "U+1F916",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Робот",
|
||||||
|
"ca": "Robot",
|
||||||
"de": "Roboter",
|
"de": "Roboter",
|
||||||
"eo": "Roboto",
|
"eo": "Roboto",
|
||||||
"es": "Robot",
|
"es": "Robot",
|
||||||
|
@ -773,6 +837,8 @@
|
||||||
"description": "Hat",
|
"description": "Hat",
|
||||||
"unicode": "U+1F3A9",
|
"unicode": "U+1F3A9",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Шапка",
|
||||||
|
"ca": "Barret",
|
||||||
"de": "Hut",
|
"de": "Hut",
|
||||||
"eo": "Ĉapelo",
|
"eo": "Ĉapelo",
|
||||||
"es": "Sombrero",
|
"es": "Sombrero",
|
||||||
|
@ -797,6 +863,8 @@
|
||||||
"description": "Glasses",
|
"description": "Glasses",
|
||||||
"unicode": "U+1F453",
|
"unicode": "U+1F453",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Очила",
|
||||||
|
"ca": "Ulleres",
|
||||||
"de": "Brille",
|
"de": "Brille",
|
||||||
"eo": "Okulvitroj",
|
"eo": "Okulvitroj",
|
||||||
"es": "Gafas",
|
"es": "Gafas",
|
||||||
|
@ -821,6 +889,8 @@
|
||||||
"description": "Spanner",
|
"description": "Spanner",
|
||||||
"unicode": "U+1F527",
|
"unicode": "U+1F527",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Гаечен ключ",
|
||||||
|
"ca": "Clau anglesa",
|
||||||
"de": "Schraubenschlüssel",
|
"de": "Schraubenschlüssel",
|
||||||
"eo": "Ŝraŭbŝlosilo",
|
"eo": "Ŝraŭbŝlosilo",
|
||||||
"es": "Llave inglesa",
|
"es": "Llave inglesa",
|
||||||
|
@ -845,6 +915,8 @@
|
||||||
"description": "Santa",
|
"description": "Santa",
|
||||||
"unicode": "U+1F385",
|
"unicode": "U+1F385",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Дядо Коледа",
|
||||||
|
"ca": "Pare Noél",
|
||||||
"de": "Nikolaus",
|
"de": "Nikolaus",
|
||||||
"eo": "Kristnaska viro",
|
"eo": "Kristnaska viro",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -869,6 +941,8 @@
|
||||||
"description": "Thumbs Up",
|
"description": "Thumbs Up",
|
||||||
"unicode": "U+1F44D",
|
"unicode": "U+1F44D",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Палец нагоре",
|
||||||
|
"ca": "Polzes amunt",
|
||||||
"de": "Daumen Hoch",
|
"de": "Daumen Hoch",
|
||||||
"eo": "Dikfingro supren",
|
"eo": "Dikfingro supren",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -893,6 +967,8 @@
|
||||||
"description": "Umbrella",
|
"description": "Umbrella",
|
||||||
"unicode": "U+2602U+FE0F",
|
"unicode": "U+2602U+FE0F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Чадър",
|
||||||
|
"ca": "Paraigües",
|
||||||
"de": "Regenschirm",
|
"de": "Regenschirm",
|
||||||
"eo": "Ombrelo",
|
"eo": "Ombrelo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -917,6 +993,8 @@
|
||||||
"description": "Hourglass",
|
"description": "Hourglass",
|
||||||
"unicode": "U+231B",
|
"unicode": "U+231B",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Пясъчен часовник",
|
||||||
|
"ca": "Rellotge de sorra",
|
||||||
"de": "Sanduhr",
|
"de": "Sanduhr",
|
||||||
"eo": "Sablohorloĝo",
|
"eo": "Sablohorloĝo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -941,6 +1019,8 @@
|
||||||
"description": "Clock",
|
"description": "Clock",
|
||||||
"unicode": "U+23F0",
|
"unicode": "U+23F0",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Часовник",
|
||||||
|
"ca": "Rellotge",
|
||||||
"de": "Wecker",
|
"de": "Wecker",
|
||||||
"eo": "Horloĝo",
|
"eo": "Horloĝo",
|
||||||
"es": "Reloj",
|
"es": "Reloj",
|
||||||
|
@ -965,6 +1045,8 @@
|
||||||
"description": "Gift",
|
"description": "Gift",
|
||||||
"unicode": "U+1F381",
|
"unicode": "U+1F381",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Подарък",
|
||||||
|
"ca": "Regal",
|
||||||
"de": "Geschenk",
|
"de": "Geschenk",
|
||||||
"eo": "Donaco",
|
"eo": "Donaco",
|
||||||
"es": "Regalo",
|
"es": "Regalo",
|
||||||
|
@ -989,6 +1071,8 @@
|
||||||
"description": "Light Bulb",
|
"description": "Light Bulb",
|
||||||
"unicode": "U+1F4A1",
|
"unicode": "U+1F4A1",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Лампа",
|
||||||
|
"ca": "Bombeta",
|
||||||
"de": "Glühbirne",
|
"de": "Glühbirne",
|
||||||
"eo": "Lampo",
|
"eo": "Lampo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1013,6 +1097,8 @@
|
||||||
"description": "Book",
|
"description": "Book",
|
||||||
"unicode": "U+1F4D5",
|
"unicode": "U+1F4D5",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Книга",
|
||||||
|
"ca": "Llibre",
|
||||||
"de": "Buch",
|
"de": "Buch",
|
||||||
"eo": "Libro",
|
"eo": "Libro",
|
||||||
"es": "Libro",
|
"es": "Libro",
|
||||||
|
@ -1037,6 +1123,8 @@
|
||||||
"description": "Pencil",
|
"description": "Pencil",
|
||||||
"unicode": "U+270FU+FE0F",
|
"unicode": "U+270FU+FE0F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Молив",
|
||||||
|
"ca": "Llapis",
|
||||||
"de": "Bleistift",
|
"de": "Bleistift",
|
||||||
"eo": "Krajono",
|
"eo": "Krajono",
|
||||||
"es": "Lápiz",
|
"es": "Lápiz",
|
||||||
|
@ -1061,6 +1149,8 @@
|
||||||
"description": "Paperclip",
|
"description": "Paperclip",
|
||||||
"unicode": "U+1F4CE",
|
"unicode": "U+1F4CE",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Кламер",
|
||||||
|
"ca": "Clip",
|
||||||
"de": "Büroklammer",
|
"de": "Büroklammer",
|
||||||
"eo": "Paperkuntenilo",
|
"eo": "Paperkuntenilo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1085,6 +1175,8 @@
|
||||||
"description": "Scissors",
|
"description": "Scissors",
|
||||||
"unicode": "U+2702U+FE0F",
|
"unicode": "U+2702U+FE0F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Ножици",
|
||||||
|
"ca": "Tisores",
|
||||||
"de": "Schere",
|
"de": "Schere",
|
||||||
"eo": "Tondilo",
|
"eo": "Tondilo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1109,6 +1201,8 @@
|
||||||
"description": "Lock",
|
"description": "Lock",
|
||||||
"unicode": "U+1F512",
|
"unicode": "U+1F512",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Катинар",
|
||||||
|
"ca": "Cadenat",
|
||||||
"de": "Schloss",
|
"de": "Schloss",
|
||||||
"eo": "Seruro",
|
"eo": "Seruro",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1133,6 +1227,8 @@
|
||||||
"description": "Key",
|
"description": "Key",
|
||||||
"unicode": "U+1F511",
|
"unicode": "U+1F511",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Ключ",
|
||||||
|
"ca": "Clau",
|
||||||
"de": "Schlüssel",
|
"de": "Schlüssel",
|
||||||
"eo": "Ŝlosilo",
|
"eo": "Ŝlosilo",
|
||||||
"es": "Llave",
|
"es": "Llave",
|
||||||
|
@ -1157,6 +1253,8 @@
|
||||||
"description": "Hammer",
|
"description": "Hammer",
|
||||||
"unicode": "U+1F528",
|
"unicode": "U+1F528",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Чук",
|
||||||
|
"ca": "Martell",
|
||||||
"de": "Hammer",
|
"de": "Hammer",
|
||||||
"eo": "Martelo",
|
"eo": "Martelo",
|
||||||
"es": "Martillo",
|
"es": "Martillo",
|
||||||
|
@ -1181,6 +1279,8 @@
|
||||||
"description": "Telephone",
|
"description": "Telephone",
|
||||||
"unicode": "U+260EU+FE0F",
|
"unicode": "U+260EU+FE0F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Телефон",
|
||||||
|
"ca": "Telèfon",
|
||||||
"de": "Telefon",
|
"de": "Telefon",
|
||||||
"eo": "Telefono",
|
"eo": "Telefono",
|
||||||
"es": "Telefono",
|
"es": "Telefono",
|
||||||
|
@ -1205,6 +1305,8 @@
|
||||||
"description": "Flag",
|
"description": "Flag",
|
||||||
"unicode": "U+1F3C1",
|
"unicode": "U+1F3C1",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Флаг",
|
||||||
|
"ca": "Bandera",
|
||||||
"de": "Flagge",
|
"de": "Flagge",
|
||||||
"eo": "Flago",
|
"eo": "Flago",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1229,6 +1331,8 @@
|
||||||
"description": "Train",
|
"description": "Train",
|
||||||
"unicode": "U+1F682",
|
"unicode": "U+1F682",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Влак",
|
||||||
|
"ca": "Tren",
|
||||||
"de": "Zug",
|
"de": "Zug",
|
||||||
"eo": "Vagonaro",
|
"eo": "Vagonaro",
|
||||||
"es": "Tren",
|
"es": "Tren",
|
||||||
|
@ -1253,6 +1357,8 @@
|
||||||
"description": "Bicycle",
|
"description": "Bicycle",
|
||||||
"unicode": "U+1F6B2",
|
"unicode": "U+1F6B2",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Колело",
|
||||||
|
"ca": "Bicicleta",
|
||||||
"de": "Fahrrad",
|
"de": "Fahrrad",
|
||||||
"eo": "Biciklo",
|
"eo": "Biciklo",
|
||||||
"es": "Bicicleta",
|
"es": "Bicicleta",
|
||||||
|
@ -1277,6 +1383,8 @@
|
||||||
"description": "Aeroplane",
|
"description": "Aeroplane",
|
||||||
"unicode": "U+2708U+FE0F",
|
"unicode": "U+2708U+FE0F",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Самолет",
|
||||||
|
"ca": "Avió",
|
||||||
"de": "Flugzeug",
|
"de": "Flugzeug",
|
||||||
"eo": "Aviadilo",
|
"eo": "Aviadilo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1301,6 +1409,8 @@
|
||||||
"description": "Rocket",
|
"description": "Rocket",
|
||||||
"unicode": "U+1F680",
|
"unicode": "U+1F680",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Ракета",
|
||||||
|
"ca": "Coet",
|
||||||
"de": "Rakete",
|
"de": "Rakete",
|
||||||
"eo": "Raketo",
|
"eo": "Raketo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1325,6 +1435,8 @@
|
||||||
"description": "Trophy",
|
"description": "Trophy",
|
||||||
"unicode": "U+1F3C6",
|
"unicode": "U+1F3C6",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Трофей",
|
||||||
|
"ca": "Trofeu",
|
||||||
"de": "Trophäe",
|
"de": "Trophäe",
|
||||||
"eo": "Trofeo",
|
"eo": "Trofeo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1349,6 +1461,8 @@
|
||||||
"description": "Ball",
|
"description": "Ball",
|
||||||
"unicode": "U+26BD",
|
"unicode": "U+26BD",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Топка",
|
||||||
|
"ca": "Pilota",
|
||||||
"de": "Ball",
|
"de": "Ball",
|
||||||
"eo": "Pilko",
|
"eo": "Pilko",
|
||||||
"es": "Bola",
|
"es": "Bola",
|
||||||
|
@ -1373,6 +1487,8 @@
|
||||||
"description": "Guitar",
|
"description": "Guitar",
|
||||||
"unicode": "U+1F3B8",
|
"unicode": "U+1F3B8",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Китара",
|
||||||
|
"ca": "Guitarra",
|
||||||
"de": "Gitarre",
|
"de": "Gitarre",
|
||||||
"eo": "Gitaro",
|
"eo": "Gitaro",
|
||||||
"es": "Guitarra",
|
"es": "Guitarra",
|
||||||
|
@ -1397,6 +1513,8 @@
|
||||||
"description": "Trumpet",
|
"description": "Trumpet",
|
||||||
"unicode": "U+1F3BA",
|
"unicode": "U+1F3BA",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Тромпет",
|
||||||
|
"ca": "Trompeta",
|
||||||
"de": "Trompete",
|
"de": "Trompete",
|
||||||
"eo": "Trumpeto",
|
"eo": "Trumpeto",
|
||||||
"es": "Trompeta",
|
"es": "Trompeta",
|
||||||
|
@ -1421,6 +1539,8 @@
|
||||||
"description": "Bell",
|
"description": "Bell",
|
||||||
"unicode": "U+1F514",
|
"unicode": "U+1F514",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Звънец",
|
||||||
|
"ca": "Campana",
|
||||||
"de": "Glocke",
|
"de": "Glocke",
|
||||||
"eo": "Sonorilo",
|
"eo": "Sonorilo",
|
||||||
"es": "Campana",
|
"es": "Campana",
|
||||||
|
@ -1445,6 +1565,8 @@
|
||||||
"description": "Anchor",
|
"description": "Anchor",
|
||||||
"unicode": "U+2693",
|
"unicode": "U+2693",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Котва",
|
||||||
|
"ca": "Àncora",
|
||||||
"de": "Anker",
|
"de": "Anker",
|
||||||
"eo": "Ankro",
|
"eo": "Ankro",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1469,6 +1591,8 @@
|
||||||
"description": "Headphones",
|
"description": "Headphones",
|
||||||
"unicode": "U+1F3A7",
|
"unicode": "U+1F3A7",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Слушалки",
|
||||||
|
"ca": "Auriculars",
|
||||||
"de": "Kopfhörer",
|
"de": "Kopfhörer",
|
||||||
"eo": "Kapaŭdilo",
|
"eo": "Kapaŭdilo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1493,6 +1617,8 @@
|
||||||
"description": "Folder",
|
"description": "Folder",
|
||||||
"unicode": "U+1F4C1",
|
"unicode": "U+1F4C1",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Папка",
|
||||||
|
"ca": "Carpeta",
|
||||||
"de": "Ordner",
|
"de": "Ordner",
|
||||||
"eo": "Dosierujo",
|
"eo": "Dosierujo",
|
||||||
"es": null,
|
"es": null,
|
||||||
|
@ -1517,6 +1643,8 @@
|
||||||
"description": "Pin",
|
"description": "Pin",
|
||||||
"unicode": "U+1F4CC",
|
"unicode": "U+1F4CC",
|
||||||
"translated_descriptions": {
|
"translated_descriptions": {
|
||||||
|
"bg": "Кабърче",
|
||||||
|
"ca": "Xinxeta",
|
||||||
"de": "Stecknadel",
|
"de": "Stecknadel",
|
||||||
"eo": "Pinglo",
|
"eo": "Pinglo",
|
||||||
"es": "Alfiler",
|
"es": "Alfiler",
|
||||||
|
|
12
event-schemas/examples/m.room_key.withheld
Normal file
12
event-schemas/examples/m.room_key.withheld
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"$ref": "core/event.json",
|
||||||
|
"type": "m.room_key.withheld",
|
||||||
|
"content": {
|
||||||
|
"algorithm": "m.megolm.v1.aes-sha2",
|
||||||
|
"room_id": "!Cuyf34gef24t:localhost",
|
||||||
|
"session_id": "X3lUlvLELLYxeTx4yOVu6UDpasGEVO0Jbu+QFnm0cKQ",
|
||||||
|
"sender_key": "RF3s+E7RkTQTGF2d8Deol0FkQvgII2aJDf3/Jp5mxVU",
|
||||||
|
"code": "m.unverified",
|
||||||
|
"reason": "Device not verified"
|
||||||
|
}
|
||||||
|
}
|
|
@ -43,6 +43,15 @@ properties:
|
||||||
to the end of the list. For example, if the key is forwarded from A to B to
|
to the end of the list. For example, if the key is forwarded from A to B to
|
||||||
C, this field is empty between A and B, and contains A's Curve25519 key between
|
C, this field is empty between A and B, and contains A's Curve25519 key between
|
||||||
B and C.
|
B and C.
|
||||||
|
withheld:
|
||||||
|
type: object
|
||||||
|
description: |-
|
||||||
|
Indicates that the key cannot be used to decrypt all the messages
|
||||||
|
from the session because a portion of the session was withheld as
|
||||||
|
described in `Reporting that decryption keys are withheld`_. This
|
||||||
|
object must include the ``code`` and ``reason`` properties from the
|
||||||
|
``m.room_key.withheld`` message that was received by the sender of
|
||||||
|
this message.
|
||||||
required:
|
required:
|
||||||
- algorithm
|
- algorithm
|
||||||
- room_id
|
- room_id
|
||||||
|
|
86
event-schemas/schema/m.room_key.withheld
Normal file
86
event-schemas/schema/m.room_key.withheld
Normal file
|
@ -0,0 +1,86 @@
|
||||||
|
---
|
||||||
|
allOf:
|
||||||
|
- $ref: core-event-schema/event.yaml
|
||||||
|
|
||||||
|
description: |-
|
||||||
|
This event type is used to indicate that the sender is not sharing room keys
|
||||||
|
with the recipient. It is sent as a to-device event.
|
||||||
|
|
||||||
|
Possible values for ``code`` include:
|
||||||
|
|
||||||
|
* ``m.blacklisted``: the user/device was blacklisted.
|
||||||
|
* ``m.unverified``: the user/device was not verified, and the sender is only
|
||||||
|
sharing keys with verified users/devices.
|
||||||
|
* ``m.unauthorised``: the user/device is not allowed to have the key. For
|
||||||
|
example, this could be sent in response to a key request if the user/device
|
||||||
|
was not in the room when the original message was sent.
|
||||||
|
* ``m.unavailable``: sent in reply to a key request if the device that the
|
||||||
|
key is requested from does not have the requested key.
|
||||||
|
* ``m.no_olm``: an olm session could not be established.
|
||||||
|
|
||||||
|
In most cases, this event refers to a specific room key. The one exception to
|
||||||
|
this is when the sender is unable to establish an olm session with the
|
||||||
|
recipient. When this happens, multiple sessions will be affected. In order
|
||||||
|
to avoid filling the recipient\'s device mailbox, the sender should only send
|
||||||
|
one ``m.room_key.withheld`` message with no ``room_id`` nor ``session_id``
|
||||||
|
set. If the sender retries and fails to create an olm session again in the
|
||||||
|
future, it should not send another ``m.room_key.withheld`` message with a
|
||||||
|
``code`` of ``m.no_olm``, unless another olm session was previously
|
||||||
|
established successfully. In response to receiving an
|
||||||
|
``m.room_key.withheld`` message with a ``code`` of ``m.no_olm``, the
|
||||||
|
recipient may start an olm session with the sender and send an ``m.dummy``
|
||||||
|
message to notify the sender of the new olm session. The recipient may
|
||||||
|
assume that this ``m.room_key.withheld`` message applies to all encrypted
|
||||||
|
room messages sent before it receives the message.
|
||||||
|
properties:
|
||||||
|
content:
|
||||||
|
properties:
|
||||||
|
algorithm:
|
||||||
|
type: string
|
||||||
|
enum: ["m.megolm.v1.aes-sha2"]
|
||||||
|
description: |-
|
||||||
|
The encryption algorithm for the key that this event is about.
|
||||||
|
room_id:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
Required if ``code`` is not ``m.no_olm``. The room for the key that
|
||||||
|
this event is about.
|
||||||
|
session_id:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
Required of ``code`` is not ``m.no_olm``. The session ID of the key
|
||||||
|
that this event is aboutis for.
|
||||||
|
sender_key:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
The unpadded base64-encoded device curve25519 key of the event\'s
|
||||||
|
sender.
|
||||||
|
code:
|
||||||
|
type: string
|
||||||
|
enum:
|
||||||
|
- m.blacklisted
|
||||||
|
- m.unverified
|
||||||
|
- m.unauthorised
|
||||||
|
- m.unavailable
|
||||||
|
- m.no_olm
|
||||||
|
description: |-
|
||||||
|
A machine-readable code for why the key was not sent. Codes beginning
|
||||||
|
with `m.` are reserved for codes defined in the Matrix
|
||||||
|
specification. Custom codes must use the Java package naming
|
||||||
|
convention.
|
||||||
|
reason:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
A human-readable reason for why the key was not sent. The receiving
|
||||||
|
client should only use this string if it does not understand the
|
||||||
|
``code``.
|
||||||
|
required:
|
||||||
|
- algorithm
|
||||||
|
- sender_key
|
||||||
|
- code
|
||||||
|
type: object
|
||||||
|
type:
|
||||||
|
enum:
|
||||||
|
- m.room_key.withheld
|
||||||
|
type: string
|
||||||
|
type: object
|
297
proposals/1543-qr_code_key_verification.md
Normal file
297
proposals/1543-qr_code_key_verification.md
Normal file
|
@ -0,0 +1,297 @@
|
||||||
|
Bi-directional Key verification using QR codes
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
Problem/Background
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Key verification is essential in ensuring that end-to-end encrypted messages
|
||||||
|
cannot be read by unauthorized parties. Traditionally, key verification is
|
||||||
|
done by comparing long strings. To save users from the tedium of reading out
|
||||||
|
long strings, some systems allow one party to verify the other party by
|
||||||
|
scanning a QR code; by doing this twice, both parties can verify each other.
|
||||||
|
In this proposal, we present a method for both parties to verify each other by
|
||||||
|
only scanning one QR code.
|
||||||
|
|
||||||
|
Proposal
|
||||||
|
--------
|
||||||
|
|
||||||
|
When Alice and Bob meet in person to verify keys, Alice will scan a QR code
|
||||||
|
generated by Bob's device. The QR code will encode both Bob's key as well as what Bob
|
||||||
|
thinks Alice's key is. When Alice scans the QR code, she will ensure that the
|
||||||
|
keys match what is expected, in which case, she relays this information to Bob,
|
||||||
|
who can then tell his device that the keys match.
|
||||||
|
|
||||||
|
### Example flow
|
||||||
|
|
||||||
|
1. Alice and Bob meet in person, and want to verify each other's keys.
|
||||||
|
2. Alice requests a key verification through her device by sending an
|
||||||
|
`m.key.verification.request` message (see
|
||||||
|
[MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)), with
|
||||||
|
`m.qr_code.show.v1`, `m.qr_code.scan.v1`, and `m.reciprocate.v1` listed in
|
||||||
|
`methods`, and Bob responds with a `m.key.verification.ready` message.
|
||||||
|
3. Alice's client displays a QR code that Bob is able to scan, and an option to
|
||||||
|
scan Bob's QR code.
|
||||||
|
4. Bob's client prompts Bob to verify Alice's key. The prompt includes a QR
|
||||||
|
code that Alice can scan (if the `m.key.verification.request` message listed
|
||||||
|
`m.qr_code.scan.v1`), and an option to scan Alice's QR code (if the
|
||||||
|
`m.key.verification.request` message listed `m.qr_code.show.v1`). The QR
|
||||||
|
code encodes:
|
||||||
|
- Bob's master cross-signing public key,
|
||||||
|
- what Bob thinks Alice's master cross-signing public key is,
|
||||||
|
- a random shared secret.
|
||||||
|
5. Alice scans Bob's QR code.
|
||||||
|
6. Alice's device ensures that:
|
||||||
|
- Bob's key encoded in the QR code matches the key that she already has for
|
||||||
|
Bob, and
|
||||||
|
- Alice's cross-signing key matches the cross-signing key encoded in the QR
|
||||||
|
code.
|
||||||
|
|
||||||
|
If any of these checks fail, Alice's device displays an error message
|
||||||
|
indicating that the code is incorrect, and sends a
|
||||||
|
`m.key.verification.cancel` message to Bob's device.
|
||||||
|
|
||||||
|
Otherwise, at this point:
|
||||||
|
- Alice's device has now verified Bob's key, and
|
||||||
|
- Alice's device knows that Bob has the correct key for her.
|
||||||
|
|
||||||
|
Thus for Bob to verify Alice's key, Alice needs to tell Bob that he has the
|
||||||
|
right key.
|
||||||
|
7. Alice's device displays a message saying that all is well. This message
|
||||||
|
tells Alice that she has the right key for Bob, and tells Bob that he has
|
||||||
|
the right key for Alice.
|
||||||
|
8. Alice's device sends a `m.key.verification.start` message with `method` set
|
||||||
|
to `m.reciprocate.v1` to Bob (see below). The message includes the shared
|
||||||
|
secret from the QR code. This signals to Bob's device that Alice has
|
||||||
|
scanned Bob's QR code.
|
||||||
|
|
||||||
|
This message is merely a signal for Bob's device to proceed to the next
|
||||||
|
step, and is not used for verification purposes.
|
||||||
|
9. Upon receipt of the `m.key.verification.start` message, Bob's device ensures
|
||||||
|
that the shared secret matches.
|
||||||
|
|
||||||
|
If the shared secret does not match, it should display an error message
|
||||||
|
indicating that an attack was attempted. (This does not affect Alice's
|
||||||
|
verification of Bob's keys.)
|
||||||
|
|
||||||
|
If the shared secret does match, it asks Bob to confirm that Alice
|
||||||
|
has scanned the QR code.
|
||||||
|
10. Bob sees Alice's device confirm that the key matches, and presses the button
|
||||||
|
on his device to indicate that Alice's key is verified.
|
||||||
|
|
||||||
|
Bob's verification of Alice's key hinges on Alice telling Bob the result of
|
||||||
|
her scan. Since the QR code includes what Bob thinks Alice's key is,
|
||||||
|
Alice's device can check whether Bob has the right key for her. Alice has
|
||||||
|
no motivation to lie about the result, as getting Bob to trust an incorrect
|
||||||
|
key would only affect communications between herself and Bob. Thus Alice
|
||||||
|
telling Bob that the code was scanned successfully is sufficient for Bob to
|
||||||
|
trust Alice's key, under the assumption that this communication is done
|
||||||
|
over a trusted medium (such as in-person).
|
||||||
|
11. Both devices send an `m.key.verification.done` message.
|
||||||
|
|
||||||
|
This flow allows Alice to verify Bob's key, and Bob to verify Alice's key.
|
||||||
|
Alice verifies Bob's key because she can trust the QR code that Bob displays
|
||||||
|
for her, as this is done over a trusted medium. Bob verifies Alice's key
|
||||||
|
because Alice can trust the QR code that Bob displays, and Bob can trust Alice
|
||||||
|
to tell him the result of the verification.
|
||||||
|
|
||||||
|
#### Self-verification
|
||||||
|
|
||||||
|
QR codes can also be used by a user to verify their own devices. These examples
|
||||||
|
shows Alice verifying two devices, one of them (Osborne2) having cross-signing
|
||||||
|
already set up, and the other one (Dynabook) having just logged in.
|
||||||
|
|
||||||
|
In the first example, Osborne2 scans Dynabook:
|
||||||
|
|
||||||
|
1. Alice logs into her new Dynabook and wants other users to be able to trust
|
||||||
|
it via cross-signing, and to trust other devices via cross-signing.
|
||||||
|
2. Dynabook retrieves Alice's public cross-signing key from the server, and
|
||||||
|
displays a QR code that encodes:
|
||||||
|
- Dynabook's device key,
|
||||||
|
- what it thinks Alice's master key is, and
|
||||||
|
- a random shared secret.
|
||||||
|
|
||||||
|
Note that in this case, the QR code does not include Alice's master key in a
|
||||||
|
`key_<key_id>` parameter, since Dynabook does not know whether it is trusted
|
||||||
|
or not.
|
||||||
|
3. Osborne2 scans the QR code displayed by Dynabook. At this point, Osborne2
|
||||||
|
knows Dynabook's device key and can sign it with the self-signing key and
|
||||||
|
upload the signature, and can trust Dynabook for sending secrets via SSSS.
|
||||||
|
It also knows that Dynabook has the correct cross-signing key.
|
||||||
|
4. Osborne2 tells Alice that the scan was successful, and sends the
|
||||||
|
`reciprocate` message containing the shared secret.
|
||||||
|
5. Upon receipt of the `reciprocate` message, Dynabook (after checking the
|
||||||
|
shared secret) confirms with Alice that she successfully scanned the QR
|
||||||
|
code.
|
||||||
|
6. Alice confirms.
|
||||||
|
7. Dynabook now knows that it can trust Alice's cross-signing keys that it
|
||||||
|
fetched from the server.
|
||||||
|
|
||||||
|
In the second example, Dynabook scans Osborne2:
|
||||||
|
|
||||||
|
1. Alice logs into her new Dynabook and wants other users to be able to trust
|
||||||
|
it via cross-signing, and to trust other devices via cross-signing.
|
||||||
|
2. Osborne2 notices that Dynabook is a new device. Osborne2 fetches Dynabook's
|
||||||
|
identity key and displays a QR code that encodes:
|
||||||
|
- what it thinks Dynabook's key is,
|
||||||
|
- Alice's master key, and
|
||||||
|
- a random shared secret.
|
||||||
|
3. Dynabook scans the QR code shown by Osborne2. At this point, Dynabook knows
|
||||||
|
Alice's cross-signing key, and so it can trust it to sign other devices. It
|
||||||
|
also knows that Osborne2 as the correct key for it.
|
||||||
|
4. Dynabook tells Alice that the scan is successful, and sends the
|
||||||
|
`reciprocate` message containing the shared secret.
|
||||||
|
5. Upon receipt of the `reciprocate` message, Osborne2 (after checking the
|
||||||
|
shared secret) confirms with Alice that she successfully scanned the QR
|
||||||
|
code.
|
||||||
|
6. Alice confirms.
|
||||||
|
7. Osborne2 now knows that it has the correct device key for Dynabook, and can
|
||||||
|
sign it with the self-signing key and upload the signature. Osborne2 can
|
||||||
|
also trust Dynabook for sending secrets via SSSS.
|
||||||
|
|
||||||
|
### Verification methods
|
||||||
|
|
||||||
|
This proposal defines three verification methods that can be used in
|
||||||
|
`m.key.verification.request` messages (see
|
||||||
|
[MSC2241](https://github.com/matrix-org/matrix-doc/pull/2241)).
|
||||||
|
|
||||||
|
- `m.qr_code.show.v2`: means that the sender of the
|
||||||
|
`m.key.verification.request` message can show a QR code that the recipient
|
||||||
|
can scan. If the recipient can scan the QR code, it should allow the user to
|
||||||
|
do so. This method is never sent as part of a `m.key.verification.start`
|
||||||
|
message.
|
||||||
|
- `m.qr_code.scan.v2`: means that the sender of the
|
||||||
|
`m.key.verification.request` message can scan a QR code displayed by the
|
||||||
|
recipient. If the recipient can display a QR code, it should allow the user
|
||||||
|
to display it so that the sender can scan it. This method is never sent as
|
||||||
|
part of a `m.key.verification.start` message.
|
||||||
|
- `m.reciprocate.v1`: means that the sender can participate in a reciprocal
|
||||||
|
verification, either as initiator or responder, as described in the [Message
|
||||||
|
types](#message-types) section below.
|
||||||
|
|
||||||
|
### QR code format
|
||||||
|
|
||||||
|
The QR codes to be displayed and scanned using this format will encode binary
|
||||||
|
strings in the general form:
|
||||||
|
|
||||||
|
- the ASCII string "MATRIX"
|
||||||
|
- one byte indicating the QR code version (must be `0x02`)
|
||||||
|
- one byte indicating the QR code verification mode. May be one of the
|
||||||
|
following values:
|
||||||
|
- `0x00` verifying another user with cross-signing
|
||||||
|
- `0x01` self-verifying in which the current device does trust the master key
|
||||||
|
- `0x02` self-verifying in which the current device does not yet trust the
|
||||||
|
master key
|
||||||
|
- the event ID or `transaction_id` of the associated verification
|
||||||
|
request event, encoded as:
|
||||||
|
- two bytes in network byte order (big-endian) indicating the length in
|
||||||
|
bytes of the ID as a UTF-8 string
|
||||||
|
- the ID as a UTF-8 string
|
||||||
|
- the first key, as 32 bytes. The key to use depends on the mode field:
|
||||||
|
- if `0x00` or `0x01`, then the current user's own master cross-signing public key
|
||||||
|
- if `0x02`, then the current device's device key
|
||||||
|
- the second key, as 32 bytes. The key to use depends on the mode field:
|
||||||
|
- if `0x00`, then what the device thinks the other user's master
|
||||||
|
cross-signing key is
|
||||||
|
- if `0x01`, then what the device thinks the other device's device key is
|
||||||
|
- if `0x02`, then what the device thinks the user's master cross-signing key
|
||||||
|
is
|
||||||
|
- a random shared secret, as a byte string. It is suggested to use a secret
|
||||||
|
that is about 8 bytes long. Note: as we do not share the length of the
|
||||||
|
secret, and it is not a fixed size, clients will just use the remainder of
|
||||||
|
binary string as the shared secret.
|
||||||
|
|
||||||
|
For example, if Alice displays a QR code encoding the following binary string:
|
||||||
|
|
||||||
|
```
|
||||||
|
"MATRIX" |ver|mode| len | event ID
|
||||||
|
4D 41 54 52 49 58 02 00 00 2D 21 41 42 43 44 ...
|
||||||
|
| user's cross-signing key | other user's cross-signing key | shared secret
|
||||||
|
00 01 02 03 04 05 06 07 ... 10 11 12 13 14 15 16 17 ... 20 21 22 23 24 25 26 27
|
||||||
|
```
|
||||||
|
|
||||||
|
this indicates that Alice is verifying another user (say Bob), in response to
|
||||||
|
the request from event "$ABCD...", her cross-signing key is
|
||||||
|
`0001020304050607...` (which is "AAECAwQFBg..." in base64), she thinks that
|
||||||
|
Bob's cross-signing key is `1011121314151617...` (which is "EBESExQVFh..." in
|
||||||
|
base64), and the shared secret is `2021222324252627` (which is "ICEiIyQlJic" in
|
||||||
|
base64).
|
||||||
|
|
||||||
|
### Message types
|
||||||
|
|
||||||
|
#### `m.key.verification.start`
|
||||||
|
|
||||||
|
Alice's device tells Bob's device that the QR code has been scanned.
|
||||||
|
|
||||||
|
message contents:
|
||||||
|
|
||||||
|
- `method`: `m.reciprocate.v1`
|
||||||
|
- `m.relates_to`: as per [key verification framework](https://github.com/matrix-org/matrix-doc/pull/2241)
|
||||||
|
- `secret`: the shared secret from the QR code, encoded using unpadded base64
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"method": "m.reciprocate.v1",
|
||||||
|
"m.relates_to": {
|
||||||
|
"rel_type": "m.reference",
|
||||||
|
"event_id": "$event_id_of_verification_request"
|
||||||
|
},
|
||||||
|
"secret": "shared+secret"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that this message could be sent by either the sender or the recipient of
|
||||||
|
the `m.key.verification.request` message, depending on which user scanned the
|
||||||
|
QR code.
|
||||||
|
|
||||||
|
### Cancellation
|
||||||
|
|
||||||
|
In addition to the cancellation codes specified in [the spec for
|
||||||
|
`m.key.verification.cancel`](https://matrix.org/docs/spec/client_server/r0.5.0#m-key-verification-cancel),
|
||||||
|
the following cancellation codes may be used:
|
||||||
|
|
||||||
|
- `m.qr_code.invalid`: The QR code is invalid (e.g. it is not a URL of the
|
||||||
|
required form)
|
||||||
|
|
||||||
|
The verification can also be cancelled with the error codes:
|
||||||
|
|
||||||
|
- `m.key_mismatch`: if the QR code has keys that do not match the expected
|
||||||
|
value
|
||||||
|
- `m.user_mismatch`: if the QR code is for a different user from what was expected
|
||||||
|
|
||||||
|
Tradeoffs/Alternatives
|
||||||
|
----------------------
|
||||||
|
|
||||||
|
Other methods of verifying keys, which do not require scanning QR codes, are
|
||||||
|
needed for devices that are unable to scan QR codes. One such method is
|
||||||
|
[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267). Since the key
|
||||||
|
verification framework allows for multiple methods to be supported, clients can
|
||||||
|
allow users to use different methods depending on their capability.
|
||||||
|
|
||||||
|
Rather than embedding the keys in the QR codes directly, the two clients could
|
||||||
|
perform an exchange similar to
|
||||||
|
[MSC1267](https://github.com/matrix-org/matrix-doc/issues/1267), and encoding
|
||||||
|
the Short Authentication String code in the QR code. However, this means that
|
||||||
|
the clients must exchange several messages before they can verify each other,
|
||||||
|
which would delay showing the QR codes. This proposal is also simpler to
|
||||||
|
implement.
|
||||||
|
|
||||||
|
This proposal does not support the case of asynchronous verification, such as
|
||||||
|
printing a QR code on a business card for others to scan. That may be address
|
||||||
|
in a separate MSC.
|
||||||
|
|
||||||
|
Security Considerations
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The security of verifying Alice's key depends on Bob not hitting the "Verified"
|
||||||
|
button (step 10 in the example flow) until after Alice's device indicates
|
||||||
|
success or failure. Users have a tendency to click on buttons without reading
|
||||||
|
what the screen says, but this is partially mitigated by the fact that it is
|
||||||
|
unlikely that Bob will be interacting with the device while Alice is scanning
|
||||||
|
and Alice's device will display the verification results immediately upon
|
||||||
|
scanning. Also, Bob's device will not display the button until it receives the
|
||||||
|
`m.key.verification.start` message that contains the shared secret from the QR
|
||||||
|
code, which means that an attacker would need to be physically present while
|
||||||
|
Alice and Bob verify. This issue can also be addressed by allowing Bob to
|
||||||
|
easily undo the verification if Alice's device displays an error.
|
51
proposals/2765-widget-avatars.md
Normal file
51
proposals/2765-widget-avatars.md
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
# MSC2765: Widget avatars
|
||||||
|
|
||||||
|
Currently widgets have a name and title associated with them, though no opportunity for avatars
|
||||||
|
for a favicon-like experience. This proposal introduces such a concept.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
A new optional paramater named `avatar_url` is added to the widget definition. This parameter is
|
||||||
|
an MXC URI to an image clients can use to associate with the widget, likely alongside the `name`
|
||||||
|
and/or `title`.
|
||||||
|
|
||||||
|
Widget avatars SHOULD be legible at small sizes, such as 20x20. The MXC URI in the `avatar_url`
|
||||||
|
should be the source material to allow clients to use the `/thumbnail` API to get a size for their
|
||||||
|
use case.
|
||||||
|
|
||||||
|
Rendering avatars is optional for clients, much like how clients are not required to use the `name`
|
||||||
|
or `title` of a widget.
|
||||||
|
|
||||||
|
An example widget would be:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"creatorUserId": "@alice:example.org",
|
||||||
|
"data": {
|
||||||
|
"custom_key": "This is a custom key",
|
||||||
|
"title": "This is a witty description for the widget"
|
||||||
|
},
|
||||||
|
"id": "20200827_WidgetExample",
|
||||||
|
"name": "My Cool Widget",
|
||||||
|
"type": "m.custom",
|
||||||
|
"url": "https://example.org/my/widget.html?roomId=$matrix_room_id",
|
||||||
|
"waitForIframeLoad": true,
|
||||||
|
"avatar_url": "mxc://example.org/abc123"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
We could define a whole structured system for different thumbnail sizes, though we have a thumbnail
|
||||||
|
API which can be used to request whatever size is needed by the client.
|
||||||
|
|
||||||
|
## Security considerations
|
||||||
|
|
||||||
|
Widget avatars could be non-images. Clients should use the thumbnail API to encourage error responses
|
||||||
|
from the server when a widget avatar is a non-image.
|
||||||
|
|
||||||
|
## Unstable prefix
|
||||||
|
|
||||||
|
While this MSC is not in a released version of the specification, clients should use an alternative
|
||||||
|
event type for widgets or use `org.matrix.msc2765.avatar_url` when using `m.widget` or `m.widgets`
|
||||||
|
as an event type.
|
54
proposals/2774-widget-id.md
Normal file
54
proposals/2774-widget-id.md
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
# MSC2774: Giving widgets their ID so they can communicate
|
||||||
|
|
||||||
|
Under the [current specification](https://github.com/matrix-org/matrix-doc/pull/2764), widgets are
|
||||||
|
able to communicate with their client host, however doing so is a bit difficult if they don't already
|
||||||
|
know their widget ID. Some widgets will be able to get their ID from another source like an
|
||||||
|
integration manager, however this is not the case for all widgets.
|
||||||
|
|
||||||
|
[MSC2762](https://github.com/matrix-org/matrix-doc/pull/2762) has a fair amount of background
|
||||||
|
information on widgets, as does the current specification linked above.
|
||||||
|
|
||||||
|
## Proposal
|
||||||
|
|
||||||
|
Currently widgets can expect a `?widgetId` query parameter sent to them in clients like Element,
|
||||||
|
however this has some issues and as such is not proposed to exist any further. One of the issues
|
||||||
|
is that the widget must retain the query string, which isn't entirely possible for some frontends
|
||||||
|
(they would instead prefer to use the fragment). It's also a privacy risk in that by being sent
|
||||||
|
through the query string, the server can be made aware of the widget ID. The widget ID doesn't
|
||||||
|
normally contain any useful information (it's an opaque string), however it's not required for
|
||||||
|
the server to function under typical usage.
|
||||||
|
|
||||||
|
The proposal is to introduce a `$matrix_widget_id` template variable for the URL, similar to the
|
||||||
|
existing `$matrix_room_id` variable. Widgets can then have their widget ID wherever they want in
|
||||||
|
the widget URL, making it easier on them to find and use.
|
||||||
|
|
||||||
|
This carries the same risks as a room ID being passed to the widget: the client can easily lie about
|
||||||
|
it, however there's no real risk involved in doing so because it's used for communication only. So
|
||||||
|
long as the client is able to identify which widget is talking to it, it doesn't really matter. It's
|
||||||
|
more of a problem if the client uses a widget ID from another widget as that could confuse the
|
||||||
|
client, however this is believed to be a bug. Clients should also be performing origin checks to
|
||||||
|
ensure the widget is talking from a sane origin and not somewhere else, like another tab or browser.
|
||||||
|
|
||||||
|
## Potential issues
|
||||||
|
|
||||||
|
This is not backwards compatible with the history of widgets so far, so clients and widgets will
|
||||||
|
need to be modified to support it. Clients which currently use the `?widgetId` parameter are
|
||||||
|
encouraged to continue supporting the parameter until sufficient adoption is reached.
|
||||||
|
|
||||||
|
## Alternatives
|
||||||
|
|
||||||
|
As mentioned, a query parameter could be used, though this has the issues previously covered. Another
|
||||||
|
solution might be to allow a single widget API action which has no widget ID solely for the purpose
|
||||||
|
of finding the widget ID, however clients are unlikely to be able to differentiate between two widgets
|
||||||
|
if this were the case.
|
||||||
|
|
||||||
|
Another solution would be to let the widget discover its widget ID by harvesting it out of the first
|
||||||
|
widget API request it sees. This can't always be relied upon (some flows require the widget to
|
||||||
|
speak first), and as the widget API becomes more capable it could become a security risk. A malicious
|
||||||
|
browser extension could spam the widget with fake requests to try and convince it to talk to it
|
||||||
|
instead of the client, thus redirecting some information to the wrong place.
|
||||||
|
|
||||||
|
## Unstable prefix
|
||||||
|
|
||||||
|
Implementations should use `$org.matrix.msc2774_widget_id` as a variable until this lands in a
|
||||||
|
released version of the specification.
|
|
@ -152,7 +152,7 @@ The complete grammar for a legal user ID is::
|
||||||
set. User IDs are primarily intended for use as an identifier at the protocol
|
set. User IDs are primarily intended for use as an identifier at the protocol
|
||||||
level, and their use as a human-readable handle is of secondary
|
level, and their use as a human-readable handle is of secondary
|
||||||
benefit. Furthermore, they are useful as a last-resort differentiator between
|
benefit. Furthermore, they are useful as a last-resort differentiator between
|
||||||
users with similar display names. Allowing the full unicode character set
|
users with similar display names. Allowing the full Unicode character set
|
||||||
would make very difficult for a human to distinguish two similar user IDs. The
|
would make very difficult for a human to distinguish two similar user IDs. The
|
||||||
limited character set used has the advantage that even a user unfamiliar with
|
limited character set used has the advantage that even a user unfamiliar with
|
||||||
the Latin alphabet should be able to distinguish similar user IDs manually, if
|
the Latin alphabet should be able to distinguish similar user IDs manually, if
|
||||||
|
@ -190,7 +190,7 @@ history includes events with a ``sender`` which does not conform. In order to
|
||||||
handle these rooms successfully, clients and servers MUST accept user IDs with
|
handle these rooms successfully, clients and servers MUST accept user IDs with
|
||||||
localparts from the expanded character set::
|
localparts from the expanded character set::
|
||||||
|
|
||||||
extended_user_id_char = %x21-39 / %x3B-7E ; all ascii printing chars except :
|
extended_user_id_char = %x21-39 / %x3B-7E ; all ASCII printing chars except :
|
||||||
|
|
||||||
Mapping from other character sets
|
Mapping from other character sets
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
@ -251,8 +251,8 @@ risk of clashes of identifiers between different homeservers. There is no
|
||||||
implication that the room or event in question is still available at the
|
implication that the room or event in question is still available at the
|
||||||
corresponding homeserver.
|
corresponding homeserver.
|
||||||
|
|
||||||
Event IDs and Room IDs are case-sensitive. They are not meant to be human
|
Event IDs and Room IDs are case-sensitive. They are not meant to be human-readable.
|
||||||
readable. They are intended to be treated as fully opaque strings by clients.
|
They are intended to be treated as fully opaque strings by clients.
|
||||||
|
|
||||||
.. TODO-spec
|
.. TODO-spec
|
||||||
What is the grammar for the opaque part? https://matrix.org/jira/browse/SPEC-389
|
What is the grammar for the opaque part? https://matrix.org/jira/browse/SPEC-389
|
||||||
|
@ -326,7 +326,7 @@ parameter is only used in the case of permalinks where an event ID is referenced
|
||||||
The matrix.to URI, when referenced, must always start with ``https://matrix.to/#/``
|
The matrix.to URI, when referenced, must always start with ``https://matrix.to/#/``
|
||||||
followed by the identifier.
|
followed by the identifier.
|
||||||
|
|
||||||
The ``<additional arguments>`` and the preceeding question mark are optional and
|
The ``<additional arguments>`` and the preceding question mark are optional and
|
||||||
only apply in certain circumstances, documented below.
|
only apply in certain circumstances, documented below.
|
||||||
|
|
||||||
Clients should not rely on matrix.to URIs falling back to a web server if accessed
|
Clients should not rely on matrix.to URIs falling back to a web server if accessed
|
||||||
|
@ -379,7 +379,7 @@ are picked is left as an implementation detail, however the current recommendati
|
||||||
to pick 3 unique servers based on the following criteria:
|
to pick 3 unique servers based on the following criteria:
|
||||||
|
|
||||||
* The first server should be the server of the highest power level user in the room,
|
* The first server should be the server of the highest power level user in the room,
|
||||||
provided they are at least power level 50. If no user meets this criteria, pick the
|
provided they are at least power level 50. If no user meets this criterion, pick the
|
||||||
most popular server in the room (most joined users). The rationale for not picking
|
most popular server in the room (most joined users). The rationale for not picking
|
||||||
users with power levels under 50 is that they are unlikely to be around into the
|
users with power levels under 50 is that they are unlikely to be around into the
|
||||||
distant future while higher ranking users (and therefore servers) are less likely
|
distant future while higher ranking users (and therefore servers) are less likely
|
||||||
|
|
|
@ -29,7 +29,7 @@ Canonical JSON
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
We define the canonical JSON encoding for a value to be the shortest UTF-8 JSON
|
We define the canonical JSON encoding for a value to be the shortest UTF-8 JSON
|
||||||
encoding with dictionary keys lexicographically sorted by unicode codepoint.
|
encoding with dictionary keys lexicographically sorted by Unicode codepoint.
|
||||||
Numbers in the JSON must be integers in the range ``[-(2**53)+1, (2**53)-1]``.
|
Numbers in the JSON must be integers in the range ``[-(2**53)+1, (2**53)-1]``.
|
||||||
|
|
||||||
We pick UTF-8 as the encoding as it should be available to all platforms and
|
We pick UTF-8 as the encoding as it should be available to all platforms and
|
||||||
|
@ -63,7 +63,7 @@ using this representation.
|
||||||
separators=(',',':'),
|
separators=(',',':'),
|
||||||
# Sort the keys of dictionaries.
|
# Sort the keys of dictionaries.
|
||||||
sort_keys=True,
|
sort_keys=True,
|
||||||
# Encode the resulting unicode as UTF-8 bytes.
|
# Encode the resulting Unicode as UTF-8 bytes.
|
||||||
).encode("UTF-8")
|
).encode("UTF-8")
|
||||||
|
|
||||||
Grammar
|
Grammar
|
||||||
|
|
|
@ -28,7 +28,7 @@ victim in order to:
|
||||||
Threat: Resource Exhaustion
|
Threat: Resource Exhaustion
|
||||||
+++++++++++++++++++++++++++
|
+++++++++++++++++++++++++++
|
||||||
|
|
||||||
An attacker could cause the victims server to exhaust a particular resource
|
An attacker could cause the victim's server to exhaust a particular resource
|
||||||
(e.g. open TCP connections, CPU, memory, disk storage)
|
(e.g. open TCP connections, CPU, memory, disk storage)
|
||||||
|
|
||||||
Threat: Unrecoverable Consistency Violations
|
Threat: Unrecoverable Consistency Violations
|
||||||
|
|
|
@ -194,7 +194,7 @@ Authorization
|
||||||
Homeservers MUST include a query parameter named ``access_token`` containing the
|
Homeservers MUST include a query parameter named ``access_token`` containing the
|
||||||
``hs_token`` from the application service's registration when making requests to
|
``hs_token`` from the application service's registration when making requests to
|
||||||
the application service. Application services MUST verify the provided ``access_token``
|
the application service. Application services MUST verify the provided ``access_token``
|
||||||
matches their known ``hs_token``, failing the request with a ``M_FORBIDDEN`` error
|
matches their known ``hs_token``, failing the request with an ``M_FORBIDDEN`` error
|
||||||
if it does not match.
|
if it does not match.
|
||||||
|
|
||||||
Legacy routes
|
Legacy routes
|
||||||
|
@ -206,8 +206,8 @@ service specification now defines a version on all endpoints to be more compatib
|
||||||
with the rest of the Matrix specification and the future.
|
with the rest of the Matrix specification and the future.
|
||||||
|
|
||||||
Homeservers should attempt to use the specified endpoints first when communicating
|
Homeservers should attempt to use the specified endpoints first when communicating
|
||||||
with application services. However, if the application service receives an http status
|
with application services. However, if the application service receives an HTTP status
|
||||||
code that does not indicate success (ie: 404, 500, 501, etc) then the homeserver
|
code that does not indicate success (i.e.: 404, 500, 501, etc) then the homeserver
|
||||||
should fall back to the older endpoints for the application service.
|
should fall back to the older endpoints for the application service.
|
||||||
|
|
||||||
The older endpoints have the exact same request body and response format, they
|
The older endpoints have the exact same request body and response format, they
|
||||||
|
|
|
@ -186,7 +186,7 @@ Other error codes the client might encounter are:
|
||||||
permits, for example, email addresses from a particular domain.
|
permits, for example, email addresses from a particular domain.
|
||||||
|
|
||||||
:``M_SERVER_NOT_TRUSTED``:
|
:``M_SERVER_NOT_TRUSTED``:
|
||||||
The client's request used a third party server, eg. identity server, that this server does not trust.
|
The client's request used a third party server, e.g. identity server, that this server does not trust.
|
||||||
|
|
||||||
:``M_UNSUPPORTED_ROOM_VERSION``:
|
:``M_UNSUPPORTED_ROOM_VERSION``:
|
||||||
The client's request to create a room used a room version that the server does not support.
|
The client's request to create a room used a room version that the server does not support.
|
||||||
|
@ -228,8 +228,8 @@ Other error codes the client might encounter are:
|
||||||
may reach a resource limit if it starts using too much memory or disk space. The
|
may reach a resource limit if it starts using too much memory or disk space. The
|
||||||
error MUST have an ``admin_contact`` field to provide the user receiving the error
|
error MUST have an ``admin_contact`` field to provide the user receiving the error
|
||||||
a place to reach out to. Typically, this error will appear on routes which attempt
|
a place to reach out to. Typically, this error will appear on routes which attempt
|
||||||
to modify state (eg: sending messages, account data, etc) and not routes which only
|
to modify state (e.g.: sending messages, account data, etc) and not routes which only
|
||||||
read state (eg: ``/sync``, get account data, etc).
|
read state (e.g.: ``/sync``, get account data, etc).
|
||||||
|
|
||||||
:``M_CANNOT_LEAVE_SERVER_NOTICE_ROOM``:
|
:``M_CANNOT_LEAVE_SERVER_NOTICE_ROOM``:
|
||||||
The user is unable to reject an invite to join the server notices room. See the
|
The user is unable to reject an invite to join the server notices room. See the
|
||||||
|
@ -266,8 +266,8 @@ to pre-flight requests and supply Cross-Origin Resource Sharing (CORS) headers o
|
||||||
all requests.
|
all requests.
|
||||||
|
|
||||||
Servers MUST expect that clients will approach them with ``OPTIONS`` requests,
|
Servers MUST expect that clients will approach them with ``OPTIONS`` requests,
|
||||||
allowing clients to discover the CORS headers. All endpoints in this specification s
|
allowing clients to discover the CORS headers. All endpoints in this specification
|
||||||
upport the ``OPTIONS`` method, however the server MUST NOT perform any logic defined
|
support the ``OPTIONS`` method, however the server MUST NOT perform any logic defined
|
||||||
for the endpoints when approached with an ``OPTIONS`` request.
|
for the endpoints when approached with an ``OPTIONS`` request.
|
||||||
|
|
||||||
When a client approaches the server with a request, the server should respond with
|
When a client approaches the server with a request, the server should respond with
|
||||||
|
@ -438,7 +438,7 @@ homeserver may provide many different ways of authenticating, such as
|
||||||
user/password auth, login via a single-sign-on server (SSO), etc. This
|
user/password auth, login via a single-sign-on server (SSO), etc. This
|
||||||
specification does not define how homeservers should authorise their users but
|
specification does not define how homeservers should authorise their users but
|
||||||
instead defines the standard interface which implementations should follow so
|
instead defines the standard interface which implementations should follow so
|
||||||
that ANY client can login to ANY homeserver.
|
that ANY client can log in to ANY homeserver.
|
||||||
|
|
||||||
The process takes the form of one or more 'stages'. At each stage the client
|
The process takes the form of one or more 'stages'. At each stage the client
|
||||||
submits a set of data for a given authentication type and awaits a response
|
submits a set of data for a given authentication type and awaits a response
|
||||||
|
@ -707,7 +707,7 @@ For example, to authenticate using the user's Matrix ID, clients would submit:
|
||||||
}
|
}
|
||||||
|
|
||||||
Alternatively reply using a 3PID bound to the user's account on the homeserver
|
Alternatively reply using a 3PID bound to the user's account on the homeserver
|
||||||
using the |/account/3pid|_ API rather then giving the ``user`` explicitly as
|
using the |/account/3pid|_ API rather than giving the ``user`` explicitly as
|
||||||
follows:
|
follows:
|
||||||
|
|
||||||
.. code:: json
|
.. code:: json
|
||||||
|
@ -827,7 +827,7 @@ Dummy Auth
|
||||||
Dummy authentication always succeeds and requires no extra parameters. Its
|
Dummy authentication always succeeds and requires no extra parameters. Its
|
||||||
purpose is to allow servers to not require any form of User-Interactive
|
purpose is to allow servers to not require any form of User-Interactive
|
||||||
Authentication to perform a request. It can also be used to differentiate
|
Authentication to perform a request. It can also be used to differentiate
|
||||||
flows where otherwise one flow would be a subset of another flow. eg. if
|
flows where otherwise one flow would be a subset of another flow. e.g. if
|
||||||
a server offers flows ``m.login.recaptcha`` and ``m.login.recaptcha,
|
a server offers flows ``m.login.recaptcha`` and ``m.login.recaptcha,
|
||||||
m.login.email.identity`` and the client completes the recaptcha stage first,
|
m.login.email.identity`` and the client completes the recaptcha stage first,
|
||||||
the auth would succeed with the former flow, even if the client was intending
|
the auth would succeed with the former flow, even if the client was intending
|
||||||
|
@ -878,7 +878,7 @@ to be defined in an embedded browser, or to use the HTML5 `cross-document
|
||||||
messaging <https://www.w3.org/TR/webmessaging/#web-messaging>`_ API, to receive
|
messaging <https://www.w3.org/TR/webmessaging/#web-messaging>`_ API, to receive
|
||||||
a notification that the authentication stage has been completed.
|
a notification that the authentication stage has been completed.
|
||||||
|
|
||||||
Once a client receives the notificaton that the authentication stage has been
|
Once a client receives the notification that the authentication stage has been
|
||||||
completed, it should resubmit the request with an auth dict with just the
|
completed, it should resubmit the request with an auth dict with just the
|
||||||
session ID:
|
session ID:
|
||||||
|
|
||||||
|
@ -891,19 +891,19 @@ session ID:
|
||||||
|
|
||||||
Example
|
Example
|
||||||
<<<<<<<
|
<<<<<<<
|
||||||
A client webapp might use the following javascript to open a popup window which will
|
A client webapp might use the following JavaScript to open a popup window which will
|
||||||
handle unknown login types:
|
handle unknown login types:
|
||||||
|
|
||||||
.. code:: javascript
|
.. code:: javascript
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Arguments:
|
* Arguments:
|
||||||
* homeserverUrl: the base url of the homeserver (eg "https://matrix.org")
|
* homeserverUrl: the base url of the homeserver (e.g. "https://matrix.org")
|
||||||
*
|
*
|
||||||
* apiEndpoint: the API endpoint being used (eg
|
* apiEndpoint: the API endpoint being used (e.g.
|
||||||
* "/_matrix/client/%CLIENT_MAJOR_VERSION%/account/password")
|
* "/_matrix/client/%CLIENT_MAJOR_VERSION%/account/password")
|
||||||
*
|
*
|
||||||
* loginType: the loginType being attempted (eg "m.login.recaptcha")
|
* loginType: the loginType being attempted (e.g. "m.login.recaptcha")
|
||||||
*
|
*
|
||||||
* sessionID: the session ID given by the homeserver in earlier requests
|
* sessionID: the session ID given by the homeserver in earlier requests
|
||||||
*
|
*
|
||||||
|
@ -930,7 +930,7 @@ handle unknown login types:
|
||||||
};
|
};
|
||||||
|
|
||||||
request({
|
request({
|
||||||
method:'POST', url:apiEndpint, json:requestBody,
|
method:'POST', url:apiEndpoint, json:requestBody,
|
||||||
}, onComplete);
|
}, onComplete);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1044,7 +1044,7 @@ request as follows:
|
||||||
}
|
}
|
||||||
|
|
||||||
Alternatively, a client can use a 3PID bound to the user's account on the
|
Alternatively, a client can use a 3PID bound to the user's account on the
|
||||||
homeserver using the |/account/3pid|_ API rather then giving the ``user``
|
homeserver using the |/account/3pid|_ API rather than giving the ``user``
|
||||||
explicitly, as follows:
|
explicitly, as follows:
|
||||||
|
|
||||||
.. code:: json
|
.. code:: json
|
||||||
|
@ -1130,7 +1130,7 @@ can be proxied (bound) to the identity server in many cases.
|
||||||
This section deals with two terms: "add" and "bind". Where "add" (or "remove")
|
This section deals with two terms: "add" and "bind". Where "add" (or "remove")
|
||||||
is used, it is speaking about an identifier that was not bound to an identity
|
is used, it is speaking about an identifier that was not bound to an identity
|
||||||
server. As a result, "bind" (or "unbind") references an identifier that is found
|
server. As a result, "bind" (or "unbind") references an identifier that is found
|
||||||
in an identity server. Note that an identifer can be added and bound at the same
|
in an identity server. Note that an identifier can be added and bound at the same
|
||||||
time, depending on context.
|
time, depending on context.
|
||||||
|
|
||||||
{{administrative_contact_cs_http_api}}
|
{{administrative_contact_cs_http_api}}
|
||||||
|
@ -1745,7 +1745,7 @@ same way a server does.
|
||||||
except those protected by the redaction algorithm. For example,
|
except those protected by the redaction algorithm. For example,
|
||||||
a redacted ``join`` event will still result in the user being considered joined.
|
a redacted ``join`` event will still result in the user being considered joined.
|
||||||
Similarly, a redacted topic does not necessarily cause the topic to revert to
|
Similarly, a redacted topic does not necessarily cause the topic to revert to
|
||||||
what is was prior to the event - it causes the topic to be removed from the room.
|
what it was prior to the event - it causes the topic to be removed from the room.
|
||||||
|
|
||||||
|
|
||||||
Events
|
Events
|
||||||
|
@ -1977,9 +1977,9 @@ many places of a client's display, changes to these fields cause an automatic
|
||||||
propagation event to occur, informing likely-interested parties of the new
|
propagation event to occur, informing likely-interested parties of the new
|
||||||
values. This change is conveyed using two separate mechanisms:
|
values. This change is conveyed using two separate mechanisms:
|
||||||
|
|
||||||
- a ``m.room.member`` event (with a ``join`` membership) is sent to every room
|
- an ``m.room.member`` event (with a ``join`` membership) is sent to every room
|
||||||
the user is a member of, to update the ``displayname`` and ``avatar_url``.
|
the user is a member of, to update the ``displayname`` and ``avatar_url``.
|
||||||
- a ``m.presence`` presence status update is sent, again containing the new
|
- an ``m.presence`` presence status update is sent, again containing the new
|
||||||
values of the ``displayname`` and ``avatar_url`` keys, in addition to the
|
values of the ``displayname`` and ``avatar_url`` keys, in addition to the
|
||||||
required ``presence`` key containing the current presence state of the user.
|
required ``presence`` key containing the current presence state of the user.
|
||||||
|
|
||||||
|
|
|
@ -225,7 +225,7 @@ Terms of service
|
||||||
|
|
||||||
Identity Servers are encouraged to have terms of service (or similar policies) to
|
Identity Servers are encouraged to have terms of service (or similar policies) to
|
||||||
ensure that users have agreed to their data being processed by the server. To facilitate
|
ensure that users have agreed to their data being processed by the server. To facilitate
|
||||||
this, an identity server can respond to almost any authenticated API endpoint with a
|
this, an identity server can respond to almost any authenticated API endpoint with an
|
||||||
HTTP 403 and the error code ``M_TERMS_NOT_SIGNED``. The error code is used to indicate
|
HTTP 403 and the error code ``M_TERMS_NOT_SIGNED``. The error code is used to indicate
|
||||||
that the user must accept new terms of service before being able to continue.
|
that the user must accept new terms of service before being able to continue.
|
||||||
|
|
||||||
|
@ -421,7 +421,7 @@ i.e. I can claim that any email address I own is associated with
|
||||||
Sessions are time-limited; a session is considered to have been modified when
|
Sessions are time-limited; a session is considered to have been modified when
|
||||||
it was created, and then when a validation is performed within it. A session can
|
it was created, and then when a validation is performed within it. A session can
|
||||||
only be checked for validation, and validation can only be performed within a
|
only be checked for validation, and validation can only be performed within a
|
||||||
session, within a 24 hour period since its most recent modification. Any
|
session, within a 24-hour period since its most recent modification. Any
|
||||||
attempts to perform these actions after the expiry will be rejected, and a new
|
attempts to perform these actions after the expiry will be rejected, and a new
|
||||||
session should be created and used instead.
|
session should be created and used instead.
|
||||||
|
|
||||||
|
|
|
@ -431,7 +431,7 @@ Profiles
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
Users may publish arbitrary key/value data associated with their account - such
|
Users may publish arbitrary key/value data associated with their account - such
|
||||||
as a human readable display name, a profile photo URL, contact information
|
as a human-readable display name, a profile photo URL, contact information
|
||||||
(email address, phone numbers, website URLs etc).
|
(email address, phone numbers, website URLs etc).
|
||||||
|
|
||||||
.. TODO
|
.. TODO
|
||||||
|
|
|
@ -83,7 +83,7 @@ Base64`_. Example:
|
||||||
"JGLn/yafz74HB2AbPLYJWIVGnKAtqECOBf11yyXac2Y"
|
"JGLn/yafz74HB2AbPLYJWIVGnKAtqECOBf11yyXac2Y"
|
||||||
|
|
||||||
The name ``signed_curve25519`` also corresponds to the Curve25519 algorithm,
|
The name ``signed_curve25519`` also corresponds to the Curve25519 algorithm,
|
||||||
but a key using this algorithm is represented by an object with a the following
|
but a key using this algorithm is represented by an object with the following
|
||||||
properties:
|
properties:
|
||||||
|
|
||||||
``KeyObject``
|
``KeyObject``
|
||||||
|
@ -431,7 +431,7 @@ Device verification may reach one of several conclusions. For example:
|
||||||
Key verification framework
|
Key verification framework
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Verifying keys manually by reading out the Ed25519 key is not very user friendly,
|
Verifying keys manually by reading out the Ed25519 key is not very user-friendly,
|
||||||
and can lead to errors. In order to help mitigate errors, and to make the process
|
and can lead to errors. In order to help mitigate errors, and to make the process
|
||||||
easier for users, some verification methods are supported by the specification.
|
easier for users, some verification methods are supported by the specification.
|
||||||
The methods all use a common framework for negotiating the key verification.
|
The methods all use a common framework for negotiating the key verification.
|
||||||
|
@ -443,7 +443,7 @@ allows Bob to reject the request on one device, and have it apply to all of his
|
||||||
devices. Similarly, it allows Bob to process the verification on one device without
|
devices. Similarly, it allows Bob to process the verification on one device without
|
||||||
having to involve all of his devices.
|
having to involve all of his devices.
|
||||||
|
|
||||||
When Bob's device receives a ``m.key.verification.request``, it should prompt Bob
|
When Bob's device receives an ``m.key.verification.request``, it should prompt Bob
|
||||||
to verify keys with Alice using one of the supported methods in the request. If
|
to verify keys with Alice using one of the supported methods in the request. If
|
||||||
Bob's device does not understand any of the methods, it should not cancel the request
|
Bob's device does not understand any of the methods, it should not cancel the request
|
||||||
as one of his other devices may support the request. Instead, Bob's device should
|
as one of his other devices may support the request. Instead, Bob's device should
|
||||||
|
@ -454,17 +454,17 @@ minutes after Bob's client receives the message, whichever comes first, if Bob
|
||||||
does not interact with the prompt. The prompt should additionally be hidden if
|
does not interact with the prompt. The prompt should additionally be hidden if
|
||||||
an appropriate ``m.key.verification.cancel`` message is received.
|
an appropriate ``m.key.verification.cancel`` message is received.
|
||||||
|
|
||||||
If Bob rejects the request, Bob's client must send a ``m.key.verification.cancel``
|
If Bob rejects the request, Bob's client must send an ``m.key.verification.cancel``
|
||||||
message to Alice's device. Upon receipt, Alice's device should tell her that Bob
|
message to Alice's device. Upon receipt, Alice's device should tell her that Bob
|
||||||
does not want to verify her device and send ``m.key.verification.cancel`` messages
|
does not want to verify her device and send ``m.key.verification.cancel`` messages
|
||||||
to all of Bob's devices to notify them that the request was rejected.
|
to all of Bob's devices to notify them that the request was rejected.
|
||||||
|
|
||||||
If Bob accepts the request, Bob's device starts the key verification process by
|
If Bob accepts the request, Bob's device starts the key verification process by
|
||||||
sending a ``m.key.verification.start`` message to Alice's device. Upon receipt
|
sending an ``m.key.verification.start`` message to Alice's device. Upon receipt
|
||||||
of this message, Alice's device should send a ``m.key.verification.cancel`` message
|
of this message, Alice's device should send an ``m.key.verification.cancel`` message
|
||||||
to all of Bob's other devices to indicate the process has been started. The start
|
to all of Bob's other devices to indicate the process has been started. The start
|
||||||
message must use the same ``transaction_id`` from the original key verification
|
message must use the same ``transaction_id`` from the original key verification
|
||||||
request if it is in response to the request. The start message can be sent indepdently
|
request if it is in response to the request. The start message can be sent independently
|
||||||
of any request.
|
of any request.
|
||||||
|
|
||||||
Individual verification methods may add additional steps, events, and properties to
|
Individual verification methods may add additional steps, events, and properties to
|
||||||
|
@ -473,7 +473,7 @@ be under the ``m.key.verification`` namespace and any other event types must be
|
||||||
according to the Java package naming convention.
|
according to the Java package naming convention.
|
||||||
|
|
||||||
Any of Alice's or Bob's devices can cancel the key verification request or process
|
Any of Alice's or Bob's devices can cancel the key verification request or process
|
||||||
at any time with a ``m.key.verification.cancel`` message to all applicable devices.
|
at any time with an ``m.key.verification.cancel`` message to all applicable devices.
|
||||||
|
|
||||||
This framework yields the following handshake, assuming both Alice and Bob each have
|
This framework yields the following handshake, assuming both Alice and Bob each have
|
||||||
2 devices, Bob's first device accepts the key verification request, and Alice's second
|
2 devices, Bob's first device accepts the key verification request, and Alice's second
|
||||||
|
@ -516,7 +516,7 @@ Short Authentication String (SAS) verification
|
||||||
|
|
||||||
SAS verification is a user-friendly key verification process built off the common
|
SAS verification is a user-friendly key verification process built off the common
|
||||||
framework outlined above. SAS verification is intended to be a highly interactive
|
framework outlined above. SAS verification is intended to be a highly interactive
|
||||||
process for users, and as such exposes verfiication methods which are easier for
|
process for users, and as such exposes verification methods which are easier for
|
||||||
users to use.
|
users to use.
|
||||||
|
|
||||||
The verification process is heavily inspired by Phil Zimmermann's ZRTP key agreement
|
The verification process is heavily inspired by Phil Zimmermann's ZRTP key agreement
|
||||||
|
@ -553,17 +553,17 @@ The process between Alice and Bob verifying each other would be:
|
||||||
#. Alice and Bob communicate which devices they'd like to verify with each other.
|
#. Alice and Bob communicate which devices they'd like to verify with each other.
|
||||||
#. Alice selects Bob's device from the device list and begins verification.
|
#. Alice selects Bob's device from the device list and begins verification.
|
||||||
#. Alice's client ensures it has a copy of Bob's device key.
|
#. Alice's client ensures it has a copy of Bob's device key.
|
||||||
#. Alice's device sends Bob's device a ``m.key.verification.start`` message.
|
#. Alice's device sends Bob's device an ``m.key.verification.start`` message.
|
||||||
#. Bob's device receives the message and selects a key agreement protocol, hash
|
#. Bob's device receives the message and selects a key agreement protocol, hash
|
||||||
algorithm, message authentication code, and SAS method supported by Alice's
|
algorithm, message authentication code, and SAS method supported by Alice's
|
||||||
device.
|
device.
|
||||||
#. Bob's device ensures it has a copy of Alice's device key.
|
#. Bob's device ensures it has a copy of Alice's device key.
|
||||||
#. Bob's device creates an ephemeral Curve25519 key pair (|BobCurve25519|), and
|
#. Bob's device creates an ephemeral Curve25519 key pair (|BobCurve25519|), and
|
||||||
calculates the hash (using the chosen algorithm) of the public key |BobPublicKey|.
|
calculates the hash (using the chosen algorithm) of the public key |BobPublicKey|.
|
||||||
#. Bob's device replies to Alice's device with a ``m.key.verification.accept`` message.
|
#. Bob's device replies to Alice's device with an ``m.key.verification.accept`` message.
|
||||||
#. Alice's device receives Bob's message and stores the commitment hash for later use.
|
#. Alice's device receives Bob's message and stores the commitment hash for later use.
|
||||||
#. Alice's device creates an ephemeral Curve25519 key pair (|AliceCurve25519|) and
|
#. Alice's device creates an ephemeral Curve25519 key pair (|AliceCurve25519|) and
|
||||||
replies to Bob's device with a ``m.key.verification.key``, sending only the public
|
replies to Bob's device with an ``m.key.verification.key``, sending only the public
|
||||||
key |AlicePublicKey|.
|
key |AlicePublicKey|.
|
||||||
#. Bob's device receives Alice's message and replies with its own ``m.key.verification.key``
|
#. Bob's device receives Alice's message and replies with its own ``m.key.verification.key``
|
||||||
message containing its public key |BobPublicKey|.
|
message containing its public key |BobPublicKey|.
|
||||||
|
@ -578,11 +578,11 @@ The process between Alice and Bob verifying each other would be:
|
||||||
#. Alice and Bob compare the strings shown by their devices, and tell their devices if
|
#. Alice and Bob compare the strings shown by their devices, and tell their devices if
|
||||||
they match or not.
|
they match or not.
|
||||||
#. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys
|
#. Assuming they match, Alice and Bob's devices calculate the HMAC of their own device keys
|
||||||
and a comma-separated sorted list of of the key IDs that they wish the other user
|
and a comma-separated sorted list of the key IDs that they wish the other user
|
||||||
to verify, using SHA-256 as the hash function. HMAC is defined in `RFC 2104 <https://tools.ietf.org/html/rfc2104>`_.
|
to verify, using SHA-256 as the hash function. HMAC is defined in `RFC 2104 <https://tools.ietf.org/html/rfc2104>`_.
|
||||||
The key for the HMAC is different for each item and is calculated by generating
|
The key for the HMAC is different for each item and is calculated by generating
|
||||||
32 bytes (256 bits) using `the key verification HKDF <#sas-hkdf>`_.
|
32 bytes (256 bits) using `the key verification HKDF <#sas-hkdf>`_.
|
||||||
#. Alice's device sends Bob's device a ``m.key.verification.mac`` message containing the
|
#. Alice's device sends Bob's device an ``m.key.verification.mac`` message containing the
|
||||||
MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does
|
MAC of Alice's device keys and the MAC of her key IDs to be verified. Bob's device does
|
||||||
the same for Bob's device keys and key IDs concurrently with Alice.
|
the same for Bob's device keys and key IDs concurrently with Alice.
|
||||||
#. When the other device receives the ``m.key.verification.mac`` message, the device
|
#. When the other device receives the ``m.key.verification.mac`` message, the device
|
||||||
|
@ -619,20 +619,20 @@ The wire protocol looks like the following between Alice and Bob's devices::
|
||||||
Error and exception handling
|
Error and exception handling
|
||||||
<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
<<<<<<<<<<<<<<<<<<<<<<<<<<<<
|
||||||
|
|
||||||
At any point the interactive verfication can go wrong. The following describes what
|
At any point the interactive verification can go wrong. The following describes what
|
||||||
to do when an error happens:
|
to do when an error happens:
|
||||||
|
|
||||||
* Alice or Bob can cancel the verification at any time. A ``m.key.verification.cancel``
|
* Alice or Bob can cancel the verification at any time. An ``m.key.verification.cancel``
|
||||||
message must be sent to signify the cancellation.
|
message must be sent to signify the cancellation.
|
||||||
* The verification can time out. Clients should time out a verification that does not
|
* The verification can time out. Clients should time out a verification that does not
|
||||||
complete within 10 minutes. Additionally, clients should expire a ``transaction_id``
|
complete within 10 minutes. Additionally, clients should expire a ``transaction_id``
|
||||||
which goes unused for 10 minutes after having last sent/received it. The client should
|
which goes unused for 10 minutes after having last sent/received it. The client should
|
||||||
inform the user that the verification timed out, and send an appropriate
|
inform the user that the verification timed out, and send an appropriate
|
||||||
``m.key.verification.cancel`` message to the other device.
|
``m.key.verification.cancel`` message to the other device.
|
||||||
* When the same device attempts to intiate multiple verification attempts, the receipient
|
* When the same device attempts to initiate multiple verification attempts, the recipient
|
||||||
should cancel all attempts with that device.
|
should cancel all attempts with that device.
|
||||||
* When a device receives an unknown ``transaction_id``, it should send an appropriate
|
* When a device receives an unknown ``transaction_id``, it should send an appropriate
|
||||||
``m.key.verfication.cancel`` message to the other device indicating as such. This
|
``m.key.verification.cancel`` message to the other device indicating as such. This
|
||||||
does not apply for inbound ``m.key.verification.start`` or ``m.key.verification.cancel``
|
does not apply for inbound ``m.key.verification.start`` or ``m.key.verification.cancel``
|
||||||
messages.
|
messages.
|
||||||
* If the two devices do not share a common key share, hash, HMAC, or SAS method then
|
* If the two devices do not share a common key share, hash, HMAC, or SAS method then
|
||||||
|
@ -792,14 +792,19 @@ Key requests
|
||||||
|
|
||||||
When a device is missing keys to decrypt messages, it can request the keys by
|
When a device is missing keys to decrypt messages, it can request the keys by
|
||||||
sending `m.room_key_request`_ to-device messages to other devices with
|
sending `m.room_key_request`_ to-device messages to other devices with
|
||||||
``action`` set to ``request``. If a device wishes to share the keys with that
|
``action`` set to ``request``.
|
||||||
device, it can forward the keys to the first device by sending an encrypted
|
|
||||||
`m.forwarded_room_key`_ to-device message. The first device should then send an
|
If a device wishes to share the keys with that device, it can forward the keys
|
||||||
`m.room_key_request`_ to-device message with ``action`` set to
|
to the first device by sending an encrypted `m.forwarded_room_key`_ to-device
|
||||||
``request_cancellation`` to the other devices that it had originally sent the key
|
message. The first device should then send an `m.room_key_request`_ to-device
|
||||||
request to; a device that receives a ``request_cancellation`` should disregard any
|
message with ``action`` set to ``request_cancellation`` to the other devices
|
||||||
previously-received ``request`` message with the same ``request_id`` and
|
that it had originally sent the key request to; a device that receives a
|
||||||
``requesting_device_id``.
|
``request_cancellation`` should disregard any previously-received ``request``
|
||||||
|
message with the same ``request_id`` and ``requesting_device_id``.
|
||||||
|
|
||||||
|
If a device does not wish to share keys with that device, it can indicate this
|
||||||
|
by sending an `m.room_key.withheld`_ to-device message, as described in
|
||||||
|
`Reporting that decryption keys are withheld`_.
|
||||||
|
|
||||||
.. NOTE::
|
.. NOTE::
|
||||||
|
|
||||||
|
@ -1164,7 +1169,7 @@ session has become corrupted and create a new one to replace it.
|
||||||
to decrypt it successfully. Olm does not have a way to recover from the failure,
|
to decrypt it successfully. Olm does not have a way to recover from the failure,
|
||||||
making this session replacement process required.
|
making this session replacement process required.
|
||||||
|
|
||||||
To establish a new session, the client sends a `m.dummy <#m-dummy>`_ to-device event
|
To establish a new session, the client sends an `m.dummy <#m-dummy>`_ to-device event
|
||||||
to the other party to notify them of the new session details.
|
to the other party to notify them of the new session details.
|
||||||
|
|
||||||
Clients should rate-limit the number of sessions it creates per device that it receives
|
Clients should rate-limit the number of sessions it creates per device that it receives
|
||||||
|
@ -1227,13 +1232,13 @@ who sent the message. The same reasoning applies, but the sender ed25519 key has
|
||||||
inferred from the ``keys.ed25519`` property of the event which established the Megolm
|
inferred from the ``keys.ed25519`` property of the event which established the Megolm
|
||||||
session.
|
session.
|
||||||
|
|
||||||
In order to enable end-to-end encryption in a room, clients can send a
|
In order to enable end-to-end encryption in a room, clients can send an
|
||||||
``m.room.encryption`` state event specifying ``m.megolm.v1.aes-sha2`` as its
|
``m.room.encryption`` state event specifying ``m.megolm.v1.aes-sha2`` as its
|
||||||
``algorithm`` property.
|
``algorithm`` property.
|
||||||
|
|
||||||
When creating a Megolm session in a room, clients must share the corresponding session
|
When creating a Megolm session in a room, clients must share the corresponding session
|
||||||
key using Olm with the intended recipients, so that they can decrypt future messages
|
key using Olm with the intended recipients, so that they can decrypt future messages
|
||||||
encrypted using this session. A ``m.room_key`` event is used to do this. Clients
|
encrypted using this session. An ``m.room_key`` event is used to do this. Clients
|
||||||
must also handle ``m.room_key`` events sent by other devices in order to decrypt their
|
must also handle ``m.room_key`` events sent by other devices in order to decrypt their
|
||||||
messages.
|
messages.
|
||||||
|
|
||||||
|
@ -1270,7 +1275,7 @@ Extensions to /sync
|
||||||
|
|
||||||
This module adds an optional ``device_lists`` property to the |/sync|_
|
This module adds an optional ``device_lists`` property to the |/sync|_
|
||||||
response, as specified below. The server need only populate this property for
|
response, as specified below. The server need only populate this property for
|
||||||
an incremental ``/sync`` (ie, one where the ``since`` parameter was
|
an incremental ``/sync`` (i.e., one where the ``since`` parameter was
|
||||||
specified). The client is expected to use |/keys/query|_ or |/keys/changes|_
|
specified). The client is expected to use |/keys/query|_ or |/keys/changes|_
|
||||||
for the equivalent functionality after an initial sync, as documented in
|
for the equivalent functionality after an initial sync, as documented in
|
||||||
`Tracking the device list for a user`_.
|
`Tracking the device list for a user`_.
|
||||||
|
@ -1333,6 +1338,32 @@ Example response:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reporting that decryption keys are withheld
|
||||||
|
-------------------------------------------
|
||||||
|
|
||||||
|
When sending an encrypted event to a room, a client can optionally signal to
|
||||||
|
other devices in that room that it is not sending them the keys needed to
|
||||||
|
decrypt the event. In this way, the receiving client can indicate to the user
|
||||||
|
why it cannot decrypt the event, rather than just showing a generic error
|
||||||
|
message.
|
||||||
|
|
||||||
|
In the same way, when one device requests keys from another using `Key
|
||||||
|
requests`_, the device from which the key is being requested may want to tell
|
||||||
|
the requester that it is purposely not sharing the key.
|
||||||
|
|
||||||
|
If Alice withholds a megolm session from Bob for some messages in a room, and
|
||||||
|
then later on decides to allow Bob to decrypt later messages, she can send Bob
|
||||||
|
the megolm session, ratcheted up to the point at which she allows Bob to
|
||||||
|
decrypt the messages. If Bob logs into a new device and uses key sharing to
|
||||||
|
obtain the decryption keys, the new device will be sent the megolm sessions
|
||||||
|
that have been ratcheted up. Bob's old device can include the reason that the
|
||||||
|
session was initially not shared by including a ``withheld`` property in the
|
||||||
|
``m.forwarded_room_key`` message that is an object with the ``code`` and
|
||||||
|
``reason`` properties from the ``m.room_key.withheld`` message.
|
||||||
|
|
||||||
|
{{m_room_key_withheld_event}}
|
||||||
|
|
||||||
|
|
||||||
.. References
|
.. References
|
||||||
|
|
||||||
.. _ed25519: http://ed25519.cr.yp.to/
|
.. _ed25519: http://ed25519.cr.yp.to/
|
||||||
|
|
|
@ -121,7 +121,7 @@ the tag and its contents and therefore may wish to exclude the tag entirely.
|
||||||
|
|
||||||
.. Note::
|
.. Note::
|
||||||
A future iteration of the specification will support more powerful and extensible
|
A future iteration of the specification will support more powerful and extensible
|
||||||
message formatting options, such as the proposal `MSC1225 <https://github.com/matrix-org/matrix-doc/issues/1225>`_.
|
message formatting options, such as the proposal `MSC1767 <https://github.com/matrix-org/matrix-doc/pull/1767>`_.
|
||||||
|
|
||||||
{{msgtype_events}}
|
{{msgtype_events}}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ is as follows:
|
||||||
Subscribing to policy lists
|
Subscribing to policy lists
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
This is deliberatly left as an implementation detail. For implementations using the
|
This is deliberately left as an implementation detail. For implementations using the
|
||||||
Client-Server API, this could be as easy as joining or peeking the room. Joining or peeking
|
Client-Server API, this could be as easy as joining or peeking the room. Joining or peeking
|
||||||
is not required, however: an implementation could poll for updates or use a different
|
is not required, however: an implementation could poll for updates or use a different
|
||||||
technique for receiving updates to the policy's rules.
|
technique for receiving updates to the policy's rules.
|
||||||
|
@ -108,7 +108,7 @@ or room alias - the subscriber is responsible for resolving the alias to a room
|
||||||
|
|
||||||
Client behaviour
|
Client behaviour
|
||||||
----------------
|
----------------
|
||||||
As described above, the client behaviour is deliberatly left undefined.
|
As described above, the client behaviour is deliberately left undefined.
|
||||||
|
|
||||||
Server behaviour
|
Server behaviour
|
||||||
----------------
|
----------------
|
||||||
|
|
|
@ -132,7 +132,7 @@ As a worked example:
|
||||||
1. Video conferencing is clearly a feature which would benefit
|
1. Video conferencing is clearly a feature which would benefit
|
||||||
the whole ecosystem, and so the spec should find a way to make it happen.
|
the whole ecosystem, and so the spec should find a way to make it happen.
|
||||||
2. Video conferencing can be achieved by widgets without requiring any
|
2. Video conferencing can be achieved by widgets without requiring any
|
||||||
compulsory changes to changes to clients nor servers to work, and so could be
|
compulsory changes to clients nor servers to work, and so could be
|
||||||
omitted from the spec.
|
omitted from the spec.
|
||||||
3. A better experience could be achieved by embedding Jitsi natively into clients
|
3. A better experience could be achieved by embedding Jitsi natively into clients
|
||||||
rather than using a widget...
|
rather than using a widget...
|
||||||
|
@ -145,10 +145,10 @@ for doing so), or to keep it as a widget-based approach (optionally with widget
|
||||||
extensions specific for more deeply integrating video conferencing use cases).
|
extensions specific for more deeply integrating video conferencing use cases).
|
||||||
|
|
||||||
As an alternative example: it's very unlikely that "how to visualise Magnetic
|
As an alternative example: it's very unlikely that "how to visualise Magnetic
|
||||||
Resonsance Imaging data over Matrix" would ever be added to the Matrix spec
|
Resonance Imaging data over Matrix" would ever be added to the Matrix spec
|
||||||
(other than perhaps a custom event type in a wider standardised Matrix event
|
(other than perhaps a custom event type in a wider standardised Matrix event
|
||||||
registry) given that the spec's existing primitives of file transfer and
|
registry) given that the spec's existing primitives of file transfer and
|
||||||
extensible events (MSC1767) give excellent tools for transfering and
|
extensible events (MSC1767) give excellent tools for transferring and
|
||||||
visualising arbitrary rich data.
|
visualising arbitrary rich data.
|
||||||
|
|
||||||
Supporting public search engines are likely to not require custom spec features
|
Supporting public search engines are likely to not require custom spec features
|
||||||
|
@ -168,7 +168,7 @@ Process
|
||||||
The process for submitting a Matrix Spec Change (MSC) Proposal in detail is as
|
The process for submitting a Matrix Spec Change (MSC) Proposal in detail is as
|
||||||
follows:
|
follows:
|
||||||
|
|
||||||
- Create a first draft of your proposal using `GitHub-flavored markdown
|
- Create a first draft of your proposal using `GitHub-flavored Markdown
|
||||||
<https://help.github.com/articles/basic-writing-and-formatting-syntax/>`_
|
<https://help.github.com/articles/basic-writing-and-formatting-syntax/>`_
|
||||||
|
|
||||||
- In the document, clearly state the problem being solved, and the possible
|
- In the document, clearly state the problem being solved, and the possible
|
||||||
|
@ -190,7 +190,7 @@ follows:
|
||||||
- The proposal must live in the ``proposals/`` directory with a filename that
|
- The proposal must live in the ``proposals/`` directory with a filename that
|
||||||
follows the format ``1234-my-new-proposal.md`` where ``1234`` is the MSC
|
follows the format ``1234-my-new-proposal.md`` where ``1234`` is the MSC
|
||||||
ID.
|
ID.
|
||||||
- Your PR description must include a link to the rendered markdown document
|
- Your PR description must include a link to the rendered Markdown document
|
||||||
and a summary of the proposal.
|
and a summary of the proposal.
|
||||||
- It is often very helpful to link any related MSCs or `matrix-doc issues
|
- It is often very helpful to link any related MSCs or `matrix-doc issues
|
||||||
<https://github.com/matrix-org/matrix-doc/issues>`_ to give context
|
<https://github.com/matrix-org/matrix-doc/issues>`_ to give context
|
||||||
|
@ -209,10 +209,10 @@ follows:
|
||||||
If preferred, an alternative room can be created and advertised in
|
If preferred, an alternative room can be created and advertised in
|
||||||
#matrix-spec:matrix.org. Please also link to the room in your PR
|
#matrix-spec:matrix.org. Please also link to the room in your PR
|
||||||
description.
|
description.
|
||||||
- For additional discussion areas, know that that #matrix-dev:matrix.org is
|
- For additional discussion areas, know that #matrix-dev:matrix.org is
|
||||||
for developers using existing Matrix APIs, #matrix:matrix.org is for users
|
for developers using existing Matrix APIs, #matrix:matrix.org is for users
|
||||||
trying to run Matrix apps (clients & servers) and
|
trying to run Matrix apps (clients & servers) and
|
||||||
#matrix-architecture:matrix.org is for cross-cutting discussion of matrix's
|
#matrix-architecture:matrix.org is for cross-cutting discussion of Matrix's
|
||||||
architectural design.
|
architectural design.
|
||||||
- The point of the spec proposal process is to be collaborative rather than
|
- The point of the spec proposal process is to be collaborative rather than
|
||||||
competitive, and to try to solve the problem in question with the optimal
|
competitive, and to try to solve the problem in question with the optimal
|
||||||
|
@ -239,7 +239,7 @@ follows:
|
||||||
the current state of the discussion, along with reasoning for its occurrence.
|
the current state of the discussion, along with reasoning for its occurrence.
|
||||||
- A concern can be raised by a Spec Core Team member at any time, which will block
|
- A concern can be raised by a Spec Core Team member at any time, which will block
|
||||||
an FCP from beginning. An FCP will only begin when 75% of the members of the
|
an FCP from beginning. An FCP will only begin when 75% of the members of the
|
||||||
Spec Core Team team agree on its outcome, and all existing concerns have been
|
Spec Core Team agree on its outcome, and all existing concerns have been
|
||||||
resolved.
|
resolved.
|
||||||
- The FCP will then begin and last for 5 days, giving anyone else some time to
|
- The FCP will then begin and last for 5 days, giving anyone else some time to
|
||||||
speak up before it concludes. On its conclusion, the disposition of the FCP
|
speak up before it concludes. On its conclusion, the disposition of the FCP
|
||||||
|
@ -332,7 +332,7 @@ Proposal Drafting and Feedback N/A A proposal docum
|
||||||
Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Spec Core Team and community
|
Proposal In Review proposal-in-review A proposal document which is now ready and waiting for review by the Spec Core Team and community
|
||||||
Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a 75% majority of team members in order to enter the final comment period
|
Proposed Final Comment Period proposed-final-comment-period Currently awaiting signoff of a 75% majority of team members in order to enter the final comment period
|
||||||
Final Comment Period final-comment-period A proposal document which has reached final comment period either for merge, closure or postponement
|
Final Comment Period final-comment-period A proposal document which has reached final comment period either for merge, closure or postponement
|
||||||
Final Commment Period Complete finished-final-comment-period The final comment period has been completed. Waiting for a demonstration implementation
|
Final Comment Period Complete finished-final-comment-period The final comment period has been completed. Waiting for a demonstration implementation
|
||||||
Spec PR Missing spec-pr-missing The proposal has been agreed, and proven with a demonstration implementation. Waiting for a PR against the Spec
|
Spec PR Missing spec-pr-missing The proposal has been agreed, and proven with a demonstration implementation. Waiting for a PR against the Spec
|
||||||
Spec PR In Review spec-pr-in-review The spec PR has been written, and is currently under review
|
Spec PR In Review spec-pr-in-review The spec PR has been written, and is currently under review
|
||||||
Spec PR Merged merged A proposal with a sufficient working implementation and whose Spec PR has been merged!
|
Spec PR Merged merged A proposal with a sufficient working implementation and whose Spec PR has been merged!
|
||||||
|
@ -352,7 +352,7 @@ an effort to pull MSCs out of that category when possible.
|
||||||
The current categories are:
|
The current categories are:
|
||||||
|
|
||||||
============ ================= ======================================
|
============ ================= ======================================
|
||||||
Name Github Label Description
|
Name GitHub Label Description
|
||||||
============ ================= ======================================
|
============ ================= ======================================
|
||||||
Core kind:core Important for the protocol's success.
|
Core kind:core Important for the protocol's success.
|
||||||
Feature kind:feature Nice to have additions to the spec.
|
Feature kind:feature Nice to have additions to the spec.
|
||||||
|
@ -379,11 +379,11 @@ As part of the proposal process the spec core team will require evidence of the
|
||||||
working in order for it to move into FCP. This can usually be a branch/pull request
|
working in order for it to move into FCP. This can usually be a branch/pull request
|
||||||
to whichever implementation of choice that proves the MSC works in practice, though
|
to whichever implementation of choice that proves the MSC works in practice, though
|
||||||
in some cases the MSC itself will be small enough to be considered proven. Where it's
|
in some cases the MSC itself will be small enough to be considered proven. Where it's
|
||||||
unclear if a MSC will require an implementation proof, ask in `#matrix-spec:matrix.org
|
unclear if an MSC will require an implementation proof, ask in `#matrix-spec:matrix.org
|
||||||
<https://matrix.to/#/#matrix-spec:matrix.org>`_.
|
<https://matrix.to/#/#matrix-spec:matrix.org>`_.
|
||||||
|
|
||||||
Early release of a MSC/idea
|
Early release of an MSC/idea
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
To help facilitate early releases of software dependent on a spec release, implementations
|
To help facilitate early releases of software dependent on a spec release, implementations
|
||||||
are required to use the following process to ensure that the official Matrix namespace
|
are required to use the following process to ensure that the official Matrix namespace
|
||||||
|
@ -447,7 +447,7 @@ is not cluttered with development or testing data.
|
||||||
.. Note::
|
.. Note::
|
||||||
MSCs MUST still describe what the stable endpoints/feature looks like with a note
|
MSCs MUST still describe what the stable endpoints/feature looks like with a note
|
||||||
towards the bottom for what the unstable feature flag/prefixes are. For example,
|
towards the bottom for what the unstable feature flag/prefixes are. For example,
|
||||||
a MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/
|
an MSC would propose `/_matrix/client/r0/new/endpoint`, not `/_matrix/client/unstable/
|
||||||
com.example/new/endpoint`.
|
com.example/new/endpoint`.
|
||||||
|
|
||||||
In summary:
|
In summary:
|
||||||
|
@ -488,7 +488,7 @@ resolve to the desired MSC, whether it started as an issue or a PR.
|
||||||
Other metadata:
|
Other metadata:
|
||||||
|
|
||||||
- The MSC number is taken from the GitHub Pull Request ID. This is carried for
|
- The MSC number is taken from the GitHub Pull Request ID. This is carried for
|
||||||
the lifetime of the proposal. These IDs do not necessary represent a
|
the lifetime of the proposal. These IDs do not necessarily represent a
|
||||||
chronological order.
|
chronological order.
|
||||||
- The GitHub PR title will act as the MSC's title.
|
- The GitHub PR title will act as the MSC's title.
|
||||||
- Please link to the spec PR (if any) by adding a "PRs: #1234" line in the
|
- Please link to the spec PR (if any) by adding a "PRs: #1234" line in the
|
||||||
|
@ -496,7 +496,7 @@ Other metadata:
|
||||||
- The creation date is taken from the GitHub PR, but can be overridden by
|
- The creation date is taken from the GitHub PR, but can be overridden by
|
||||||
adding a "Date: yyyy-mm-dd" line in the PR description.
|
adding a "Date: yyyy-mm-dd" line in the PR description.
|
||||||
- Updated Date is taken from GitHub.
|
- Updated Date is taken from GitHub.
|
||||||
- Author is the creator of the MSC PR, but can be overridden by adding a
|
- Author is the creator of the MSC PR, but can be overridden by adding an
|
||||||
"Author: @username" line in the body of the issue description. Please make
|
"Author: @username" line in the body of the issue description. Please make
|
||||||
sure @username is a GitHub user (include the @!)
|
sure @username is a GitHub user (include the @!)
|
||||||
- A shepherd can be assigned by adding a "Shepherd: @username" line in the
|
- A shepherd can be assigned by adding a "Shepherd: @username" line in the
|
||||||
|
|
|
@ -731,7 +731,7 @@ In summary, the remote join handshake consists of the joining server querying
|
||||||
the directory server for information about the room alias; receiving a room ID
|
the directory server for information about the room alias; receiving a room ID
|
||||||
and a list of join candidates. The joining server then requests information
|
and a list of join candidates. The joining server then requests information
|
||||||
about the room from one of the residents. It uses this information to construct
|
about the room from one of the residents. It uses this information to construct
|
||||||
a ``m.room.member`` event which it finally sends to a resident server.
|
an ``m.room.member`` event which it finally sends to a resident server.
|
||||||
|
|
||||||
Conceptually these are three different roles of homeserver. In practice the
|
Conceptually these are three different roles of homeserver. In practice the
|
||||||
directory server is likely to be resident in the room, and so may be selected
|
directory server is likely to be resident in the room, and so may be selected
|
||||||
|
@ -822,7 +822,7 @@ Similar to the `Joining Rooms`_ handshake, the server which wishes to leave the
|
||||||
room starts with sending a ``/make_leave`` request to a resident server. In the
|
room starts with sending a ``/make_leave`` request to a resident server. In the
|
||||||
case of rejecting invites, the resident server may be the server which sent the
|
case of rejecting invites, the resident server may be the server which sent the
|
||||||
invite. After receiving a template event from ``/make_leave``, the leaving server
|
invite. After receiving a template event from ``/make_leave``, the leaving server
|
||||||
signs the event and replaces the ``event_id`` with it's own. This is then sent to
|
signs the event and replaces the ``event_id`` with its own. This is then sent to
|
||||||
the resident server via ``/send_leave``. The resident server will then send the
|
the resident server via ``/send_leave``. The resident server will then send the
|
||||||
event to other servers in the room.
|
event to other servers in the room.
|
||||||
|
|
||||||
|
@ -837,7 +837,7 @@ Third-party invites
|
||||||
More information about third party invites is available in the `Client-Server API`_
|
More information about third party invites is available in the `Client-Server API`_
|
||||||
under the Third Party Invites module.
|
under the Third Party Invites module.
|
||||||
|
|
||||||
When an user wants to invite another user in a room but doesn't know the Matrix
|
When a user wants to invite another user in a room but doesn't know the Matrix
|
||||||
ID to invite, they can do so using a third-party identifier (e.g. an e-mail or a
|
ID to invite, they can do so using a third-party identifier (e.g. an e-mail or a
|
||||||
phone number).
|
phone number).
|
||||||
|
|
||||||
|
@ -856,7 +856,7 @@ Cases where an association doesn't exist for a third-party identifier
|
||||||
|
|
||||||
If the third-party identifier isn't bound to any Matrix ID, the inviting
|
If the third-party identifier isn't bound to any Matrix ID, the inviting
|
||||||
homeserver will request the identity server to store an invite for this identifier
|
homeserver will request the identity server to store an invite for this identifier
|
||||||
and to deliver it to whoever binds it to its Matrix ID. It will also send a
|
and to deliver it to whoever binds it to its Matrix ID. It will also send an
|
||||||
``m.room.third_party_invite`` event in the room to specify a display name, a token
|
``m.room.third_party_invite`` event in the room to specify a display name, a token
|
||||||
and public keys the identity server provided as a response to the invite storage
|
and public keys the identity server provided as a response to the invite storage
|
||||||
request.
|
request.
|
||||||
|
@ -867,7 +867,7 @@ in the `Invitation Storage`_ section of the Identity Service API.
|
||||||
|
|
||||||
The following process applies for each invite sent by the identity server:
|
The following process applies for each invite sent by the identity server:
|
||||||
|
|
||||||
The invited homeserver will create a ``m.room.member`` invite event containing
|
The invited homeserver will create an ``m.room.member`` invite event containing
|
||||||
a special ``third_party_invite`` section containing the token and a signed object,
|
a special ``third_party_invite`` section containing the token and a signed object,
|
||||||
both provided by the identity server.
|
both provided by the identity server.
|
||||||
|
|
||||||
|
@ -882,7 +882,7 @@ will need to request the room's homeserver to auth the event.
|
||||||
Verifying the invite
|
Verifying the invite
|
||||||
++++++++++++++++++++
|
++++++++++++++++++++
|
||||||
|
|
||||||
When a homeserver receives a ``m.room.member`` invite event for a room it's in
|
When a homeserver receives an ``m.room.member`` invite event for a room it's in
|
||||||
with a ``third_party_invite`` object, it must verify that the association between
|
with a ``third_party_invite`` object, it must verify that the association between
|
||||||
the third-party identifier initially invited to the room and the Matrix ID that
|
the third-party identifier initially invited to the room and the Matrix ID that
|
||||||
claims to be bound to it has been verified without having to rely on a third-party
|
claims to be bound to it has been verified without having to rely on a third-party
|
||||||
|
@ -949,7 +949,7 @@ Receipts are EDUs used to communicate a marker for a given event. Currently the
|
||||||
only kind of receipt supported is a "read receipt", or where in the event graph
|
only kind of receipt supported is a "read receipt", or where in the event graph
|
||||||
the user has read up to.
|
the user has read up to.
|
||||||
|
|
||||||
Read receipts for events events that a user sent do not need to be sent. It is
|
Read receipts for events that a user sent do not need to be sent. It is
|
||||||
implied that by sending the event the user has read up to the event.
|
implied that by sending the event the user has read up to the event.
|
||||||
|
|
||||||
{{definition_ss_event_schemas_m_receipt}}
|
{{definition_ss_event_schemas_m_receipt}}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue