Merge branch 'master' of github.com:matrix-org/matrix-doc into erikj/public_rooms

pull/977/head
Erik Johnston 8 years ago
commit a69d6c63c6

@ -170,7 +170,12 @@ paths:
``public_chat``: =>
``join_rules`` is set to ``public``.
``history_visibility`` is set to ``shared``.
is_direct:
type: boolean
description: |-
This flag makes the server set the ``is_direct`` flag on the
``m.room.member`` events sent to the users in ``invite`` and
``invite_3pid``. See `Direct Messaging`_ for more information.
responses:
200:
description: Information about the newly created room.

@ -28,4 +28,8 @@ properties:
items:
type: string
type: array
contains_url:
type: boolean
description: If ``true``, includes only events with a url key in their content. If
``false``, excludes those events.
type: object

@ -13,6 +13,6 @@
# limitations under the License.
accessToken:
type: apiKey
description: The access_token returned by a call to ``/login`` or ``/tokenrefresh``
description: The access_token returned by a call to ``/login`` or ``/register``
name: access_token
in: query

@ -90,15 +90,6 @@ paths:
description: |-
An access token for the account.
This access token can then be used to authorize other requests.
The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``.
There is no specific error message to indicate that a request has failed because
an access token has expired; instead, if a client has reason to believe its
access token is valid, and it receives an auth error, they should attempt to
refresh for a new token on failure, and retry the request with the new token.
refresh_token:
type: string
description: |-
Optional. A ``refresh_token`` may be exchanged for a new ``access_token`` using the |/tokenrefresh|_ API endpoint.
home_server:
type: string
description: The hostname of the homeserver on which the account has been registered.
@ -123,67 +114,3 @@ paths:
"$ref": "definitions/error.yaml"
tags:
- Session management
"/tokenrefresh":
post:
summary: Exchanges a refresh token for an access token.
description: |-
Exchanges a refresh token for a new access token.
This is intended to be used if the access token has expired.
The server MUST invalidate the supplied ``refresh_token`` if the
request is successful. It MUST also invalidate the ``access_token``
which was issued at the same time as the ``refresh_token``, if it
has not already expired.
security:
- accessToken: []
parameters:
- in: body
name: body
schema:
type: object
example: |-
{
"refresh_token": "a1b2c3"
}
properties:
refresh_token:
type: string
description: The refresh token which was issued by the server.
required: ["refresh_token"]
responses:
200:
description: |-
The refresh token was accepted, and a new access token has been issued.
The passed refresh token is no longer valid and cannot be used.
A new refresh token will have been returned unless some policy does
not allow the user to continue to renew their session.
examples:
application/json: |-
{
"access_token": "bearwithme123",
"refresh_token": "exchangewithme987"
}
schema:
type: object
properties:
access_token:
type: string
description: |-
An access token for the account.
This access token can then be used to authorize other requests.
The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``.
refresh_token:
type: string
description: Optional. A new ``refresh_token`` which may be exchanged for another new ``access_token``.
403:
description: |-
The exchange attempt failed. For example, the refresh token may have already been used.
examples:
application/json: |-
{"errcode": "M_FORBIDDEN"}
429:
description: This request was rate-limited.
schema:
"$ref": "definitions/error.yaml"
tags:
- Session management

@ -75,6 +75,13 @@ paths:
description: |-
The maximum number of events to return. Default: 10.
x-example: "3"
- in: query
type: string
name: filter
description: |-
A JSON RoomEventFilter to filter returned events with.
x-example: |-
{"contains_url":true}
responses:
200:
description: A list of messages with a new token to request more.

@ -0,0 +1,142 @@
# Copyright 2016 OpenMarket Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Client-Server Notifications API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/notifications":
get:
summary: Gets a list of events that the user has been notified about
description: |-
This API is used to paginate through the list of events that the
user has been, or would have been notified about.
security:
- accessToken: []
parameters:
- in: query
type: string
name: from
description: Pagination token given to retrieve the next set of events.
required: false
x-example: "xxxxx"
- in: query
type: number
name: limit
description: Limit on the number of events to return in this request.
required: false
x-example: "20"
- in: query
name: only
type: string
description: |-
Allows basic filtering of events returned. Supply ``highlight``
to return only events where the notification had the highlight
tweak set.
required: false
x-example: "highlight"
responses:
200:
description: A batch of events is being returned
examples:
application/json: |-
{
"next_token": "abcdef",
"notifications": [
{
"actions": [
"notify"
],
"profile_tag": "hcbvkzxhcvb",
"read": true,
"room_id": "!abcdefg:example.com",
"ts": 1475508881945,
"event": {
"sender": "@alice:example.com",
"type": "m.room.message",
"age": 124524,
"txn_id": "1234",
"content": {
"body": "I am a fish",
"msgtype": "m.text"
},
"origin_server_ts": 1417731086797,
"event_id": "$74686972643033:example.com"
}
}
]
}
schema:
type: object
required: ["notifications"]
properties:
next_token:
type: string
description: |-
The token to supply in the ``from`` param of the next
``/notifications`` request in order to request more
events. If this is absent, there are no more results.
notifications:
type: array
items:
type: object
required: ["actions", "event", "read", "room_id", "ts"]
title: Notification
properties:
actions:
type: array
description: |-
The action(s) to perform when the conditions for this rule are met.
See `Push Rules: API`_.
items:
type:
- object
- string
event:
type: object
title: Event
description: The Event object for the event that triggered the notification.
allOf:
- "$ref": "definitions/event.yaml"
profile_tag:
type: string
description: The profile tag of the rule that matched this event.
read:
type: boolean
description: |-
Indicates whether the user has sent a read receipt indicating
that they have read this message.
room_id:
type: string
description: The ID of the room in which the event was posted.
ts:
type: integer
description: |-
The unix timestamp at which the event notification was sent,
in milliseconds.
description: The list of events that triggered notifications.
tags:
- Push notifications

@ -39,6 +39,9 @@ paths:
- `guest` accounts. These accounts may have limited permissions and may not be supported by all servers.
If registration is successful, this endpoint will issue an access token
the client can use to authorize itself in subsequent requests.
parameters:
- in: query
name: kind
@ -90,8 +93,7 @@ paths:
{
"user_id": "@cheeky_monkey:matrix.org",
"access_token": "abc123",
"home_server": "matrix.org",
"refresh_token": "def456"
"home_server": "matrix.org"
}
schema:
type: object
@ -104,16 +106,6 @@ paths:
description: |-
An access token for the account.
This access token can then be used to authorize other requests.
The access token may expire at some point, and if so, it SHOULD come with a ``refresh_token``.
There is no specific error message to indicate that a request has failed because
an access token has expired; instead, if a client has reason to believe its
access token is valid, and it receives an auth error, they should attempt to
refresh for a new token on failure, and retry the request with the new token.
refresh_token:
type: string
# TODO: Work out how to linkify /tokenrefresh
description: |-
(optional) A ``refresh_token`` may be exchanged for a new ``access_token`` using the /tokenrefresh API endpoint.
home_server:
type: string
description: The hostname of the homeserver on which the account has been registered.

@ -246,7 +246,7 @@ paths:
200:
description: |-
A list of members of the room. If you are joined to the room then
this will be the current members of the room. If you have left te
this will be the current members of the room. If you have left the
room then this will be the members of the room when you left.
examples:
application/json: |-

@ -236,6 +236,12 @@ paths:
The global private data created by this user.
allOf:
- $ref: "definitions/event_batch.yaml"
to_device:
title: ToDevice
type: object
description: |-
Information on the send-to-device messages for the client
device, as defined in |send_to_device_sync|_.
examples:
application/json: |-
{

@ -0,0 +1,89 @@
# Copyright 2016 OpenMarket Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
swagger: '2.0'
info:
title: "Matrix Client-Server Send-to-device API"
version: "1.0.0"
host: localhost:8008
schemes:
- https
- http
basePath: /_matrix/client/%CLIENT_MAJOR_VERSION%
consumes:
- application/json
produces:
- application/json
securityDefinitions:
$ref: definitions/security.yaml
paths:
"/sendToDevice/{eventType}/{txnId}":
put:
summary: Send an event to a given set of devices.
description: |-
This endpoint is used to send send-to-device events to a set of
client devices.
security:
- accessToken: []
parameters:
- in: path
type: string
name: eventType
description: The type of event to send.
required: true
x-example: "m.new_device"
- in: path
name: txnId
type: string
description: |-
The transaction ID for this event. Clients should generate an
ID unique across requests with the same access token; it will be
used by the server to ensure idempotency of requests.
required: true
x-example: "35"
- in: body
name: body
required: true
schema:
type: object
title: body
properties:
messages:
type: object
description: |-
The messages to send. A map from user ID, to a map from
device ID to message body. The device ID may also be `*`,
meaning all known devices for the user.
additionalProperties:
type: object
additionalProperties:
type: object
title: EventContent
description: Message content
example: {
"@alice:example.com": {
"TLLBEANAAG": {
"example_content_key": "value"
}
}
}
responses:
200:
description:
The message was successfully sent.
examples:
application/json: |-
{}
tags:
- Send-to-Device messaging

@ -19,7 +19,7 @@ host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/v1/api
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:

@ -19,7 +19,7 @@ host: localhost:8090
schemes:
- https
- http
basePath: /_matrix/identity/v1/api
basePath: /_matrix/identity/api/v1
produces:
- application/json
paths:

@ -8,21 +8,11 @@
which support push rules, but any other clients implementing
the push rules API should be aware of this change. This
makes it simple to mute rooms correctly in the API.
- Spec clarifications:
- Spell out the way that state is handled by ``POST /createRoom``
(`#362 <https://github.com/matrix-org/matrix-doc/pull/362>`_).
- Emphasise that ``POST /tokenrefresh`` should expire the access token
(`#363 <https://github.com/matrix-org/matrix-doc/pull/363>`_).
- Clarify the fields which are applicable to different types of push rule
(`#365 <https://github.com/matrix-org/matrix-doc/pull/365>`_).
- A number of clarifications to authentication
(`#371 <https://github.com/matrix-org/matrix-doc/pull/371>`_).
- Correct references to ``user_id`` which should have been ``sender``
(`#376 <https://github.com/matrix-org/matrix-doc/pull/376>`_).
- Correct inconsistent specification of ``redacted_because`` fields and their
values (`#378 <https://github.com/matrix-org/matrix-doc/pull/378>`_).
(`#373 <https://github.com/matrix-org/matrix-doc/pull/373>`_).
- Remove ``/tokenrefresh`` from the API.
(`#395 <https://github.com/matrix-org/matrix-doc/pull/395>`_).
- Remove requirement that tokens used in token-based login be macaroons.
(`#395 <https://github.com/matrix-org/matrix-doc/pull/395>`_).
- Changes to the API which will be backwards-compatible for clients:
@ -35,11 +25,38 @@
- Add top-level ``account_data`` key to the responses to ``GET /sync`` and
``GET /initialSync``
(`#380 <https://github.com/matrix-org/matrix-doc/pull/380>`_).
- Add ``is_direct`` flag to |/createRoom|_ and invite member event.
Add 'Direct Messaging' module.
(`#389 <https://github.com/matrix-org/matrix-doc/pull/389>`_).
- Add ``contains_url`` option to ``RoomEventFilter``.
(`#390 <https://github.com/matrix-org/matrix-doc/pull/390>`_).
- Add ``filter`` optional query param to ``/messages``
(`#390 <https://github.com/matrix-org/matrix-doc/pull/390>`_).
- Add "Send-to-Device messaging" module
(`#386 <https://github.com/matrix-org/matrix-doc/pull/386>`_).
- Require that User-Interactive auth fallback pages call
``window.postMessage`` to notify apps of completion
(`#398 <https://github.com/matrix-org/matrix-doc/pull/398>`_).
- Add pagination and filter support to ``/publicRooms``. Change response to
omit fields rather than return ``null``. Add estimate of total number of
rooms in list.
(`#388 <https://github.com/matrix-org/matrix-doc/pull/388>`_).
- Spec clarifications:
- Spell out the way that state is handled by ``POST /createRoom``
(`#362 <https://github.com/matrix-org/matrix-doc/pull/362>`_).
- Clarify the fields which are applicable to different types of push rule
(`#365 <https://github.com/matrix-org/matrix-doc/pull/365>`_).
- A number of clarifications to authentication
(`#371 <https://github.com/matrix-org/matrix-doc/pull/371>`_).
- Correct references to ``user_id`` which should have been ``sender``
(`#376 <https://github.com/matrix-org/matrix-doc/pull/376>`_).
- Correct inconsistent specification of ``redacted_because`` fields and their
values (`#378 <https://github.com/matrix-org/matrix-doc/pull/378>`_).
- Mark required fields in response objects as such
(`#394 <https://github.com/matrix-org/matrix-doc/pull/394>`_).
r0.2.0
======

@ -0,0 +1,9 @@
{
"type": "m.direct",
"content": {
"@bob:example.com": [
"!abcdefgh:example.com",
"!hgfedcba:example.com"
]
}
}

@ -0,0 +1,21 @@
---
allOf:
- $ref: core-event-schema/event.yaml
description: |-
A map of which rooms are considered 'direct' rooms for specific users
is kept in ``account_data`` in an event of type ``m.direct``. The
content of this event is an object where the keys are the user IDs
and values are lists of room ID strings of the 'direct' rooms for
that user ID.
properties:
content:
additionalProperties:
type: array
title: User ID
type: object
type:
enum:
- m.direct
type: string
title: Direct Chat Mapping
type: object

@ -39,6 +39,9 @@ properties:
- leave
- ban
type: string
is_direct:
description: Flag indicating if the room containing this event was created with the intention of being a direct chat. See `Direct Messaging`_.
type: boolean
third_party_invite:
properties:
display_name:

@ -27,6 +27,7 @@ import (
"strings"
"sync"
"syscall"
"text/template"
"time"
"github.com/hashicorp/golang-lru"
@ -83,19 +84,15 @@ func accessTokenQuerystring() string {
return fmt.Sprintf("?access_token=%s", *accessToken)
}
func gitClone(url string, shared bool) (string, error) {
directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10))
if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil {
return "", fmt.Errorf("error making directory %s: %v", directory, err)
}
func gitClone(url string, directory string, shared bool) error {
args := []string{"clone", url, directory}
if shared {
args = append(args, "--shared")
}
if err := runGitCommand(directory, args); err != nil {
return "", err
return err
}
return directory, nil
return nil
}
func gitCheckout(path, sha string) error {
@ -159,6 +156,16 @@ func generate(dir string) error {
if err := cmd.Run(); err != nil {
return fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String())
}
// cheekily dump the swagger docs into the gen directory so they can be
// served by serveSpec
cmd = exec.Command("python", "dump-swagger.py", "gen/api-docs.json")
cmd.Dir = path.Join(dir, "scripts")
cmd.Stderr = &b
if err := cmd.Run(); err != nil {
return fmt.Errorf("error generating api docs: %v\nOutput from dump-swagger:\n%v", err, b.String())
}
return nil
}
@ -195,8 +202,14 @@ func (s *server) generateAt(sha string) (dst string, err error) {
return
}
}
dst, err = makeTempDir()
if err != nil {
return
}
log.Printf("Generating %s in %s\n", sha, dst)
s.mu.Lock()
dst, err = gitClone(s.matrixDocCloneURL, true)
err = gitClone(s.matrixDocCloneURL, dst, true)
s.mu.Unlock()
if err != nil {
return
@ -219,7 +232,7 @@ func (s *server) getSHAOf(ref string) (string, error) {
err := cmd.Run()
s.mu.Unlock()
if err != nil {
return "", fmt.Errorf("error generating spec: %v\nOutput from gendoc:\n%v", err, b.String())
return "", fmt.Errorf("error generating spec: %v\nOutput from git:\n%v", err, b.String())
}
return strings.TrimSpace(b.String()), nil
}
@ -396,6 +409,11 @@ func (s *server) serveSpec(w http.ResponseWriter, req *http.Request) {
cache.Add(sha, pathToContent)
}
if requestedPath == "api-docs.json" {
// allow other swagger UIs access to our swagger
w.Header().Set("Access-Control-Allow-Origin", "*")
}
if b, ok := pathToContent[requestedPath]; ok {
w.Write(b)
return
@ -588,12 +606,6 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) {
writeError(w, 500, err)
return
}
s := "<body><ul>"
for _, pull := range pulls {
s += fmt.Sprintf(`<li>%d: <a href="%s">%s</a>: <a href="%s">%s</a>: <a href="spec/%d/">spec</a> <a href="diff/html/%d/">spec diff</a> <a href="diff/rst/%d/">rst diff</a></li>`,
pull.Number, pull.User.HTMLURL, pull.User.Login, pull.HTMLURL, pull.Title, pull.Number, pull.Number, pull.Number)
}
s += "</ul>"
branches, err := srv.getBranches()
if err != nil {
@ -601,7 +613,48 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) {
return
}
s += `<div>View the spec at:<ul>`
// write our stuff into a buffer so that we can change our minds
// and write a 500 if it all goes wrong.
var b bytes.Buffer
b.Write([]byte(`
<head>
<script>
function redirectToApiDocs(relativePath) {
var url = new URL(window.location);
url.pathname += relativePath;
var newLoc = "http://matrix.org/docs/api/client-server/?url=" + encodeURIComponent(url);
window.location = newLoc;
}
</script>
</head>
<body><ul>
`))
tmpl, err := template.New("pr entry").Parse(`
<li>{{.Number}}:
<a href="{{.User.HTMLURL}}">{{.User.Login}}</a>:
<a href="{{.HTMLURL}}">{{.Title}}</a>:
<a href="spec/{{.Number}}/">spec</a>
<a href="#" onclick="redirectToApiDocs('spec/{{.Number}}/api-docs.json')">api docs</a>
<a href="diff/html/{{.Number}}/">spec diff</a>
<a href="diff/rst/{{.Number}}/">rst diff</a>
</li>
`)
if err != nil {
log.Fatal(err)
}
for _, pull := range pulls {
err = tmpl.Execute(&b, pull)
if err != nil {
writeError(w, 500, err)
return
}
}
b.Write([]byte(`
</ul>
<div>View the spec at:<ul>
`))
branchNames := []string{}
for _, branch := range branches {
if strings.HasPrefix(branch, "drafts/") {
@ -611,15 +664,14 @@ func (srv *server) makeIndex(w http.ResponseWriter, req *http.Request) {
branchNames = append(branchNames, "HEAD")
for _, branch := range branchNames {
href := "spec/" + url.QueryEscape(branch) + "/"
s += fmt.Sprintf(`<li><a href="%s">%s</a></li>`, href, branch)
fmt.Fprintf(&b, `<li><a href="%s">%s</a></li>`, href, branch)
if *includesDir != "" {
s += fmt.Sprintf(`<li><a href="%s?matrixdotorgstyle=1">%s, styled like matrix.org</a></li>`,
fmt.Fprintf(&b, `<li><a href="%s?matrixdotorgstyle=1">%s, styled like matrix.org</a></li>`,
href, branch)
}
}
s += "</ul></div></body>"
io.WriteString(w, s)
b.Write([]byte("</ul></div></body>"))
b.WriteTo(w)
}
func ignoreExitCodeOne(err error) error {
@ -655,10 +707,14 @@ func main() {
log.Fatal(err)
}
rand.Seed(time.Now().Unix())
masterCloneDir, err := gitClone(matrixDocCloneURL, false)
masterCloneDir, err := makeTempDir()
if err != nil {
log.Fatal(err)
}
log.Printf("Creating master clone dir %s\n", masterCloneDir)
if err = gitClone(matrixDocCloneURL, masterCloneDir, false); err != nil {
log.Fatal(err)
}
s := server{matrixDocCloneURL: masterCloneDir}
http.HandleFunc("/spec/", forceHTML(s.serveSpec))
http.HandleFunc("/diff/rst/", s.serveRSTDiff)
@ -691,3 +747,11 @@ func initCache() error {
styledSpecCache = c2
return err
}
func makeTempDir() (string, error) {
directory := path.Join("/tmp/matrix-doc", strconv.FormatInt(rand.Int63(), 10))
if err := os.MkdirAll(directory, permissionsOwnerFull); err != nil {
return "", fmt.Errorf("error making directory %s: %v", directory, err)
}
return directory, nil
}

@ -158,14 +158,23 @@ recommended.
Client Authentication
---------------------
Most API endpoints require the user to identify themselves by presenting
previously obtained credentials in the form of an ``access_token`` query
parameter.
parameter. An access token is typically obtained via the `Login`_ or
`Registration`_ processes.
When credentials are required but missing or invalid, the HTTP call will
return with a status of 401 and the error code, ``M_MISSING_TOKEN`` or
``M_UNKNOWN_TOKEN`` respectively.
.. NOTE::
This specification does not mandate a particular format for the access
token. Clients should treat it as an opaque byte sequence. Servers are free
to choose an appropriate format. Server implementors may like to investigate
`macaroons <macaroon_>`_.
User-Interactive Authentication API
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -249,7 +258,7 @@ complete auth type ``example.type.foo``, it might submit something like this:
POST /_matrix/client/r0/endpoint HTTP/1.1
Content-Type: application/json
{
"a_request_parameter": "something",
"another_request_parameter": "something else",
@ -289,8 +298,42 @@ successfully:
"session": "xxxxxx"
}
If the homeserver decides the attempt was unsuccessful, it returns an error
message in the standard format:
Individual stages may require more than one request to complete, in which case
the response will be as if the request was unauthenticated with the addition of
any other keys as defined by the auth type.
If the homeserver decides that an attempt on a stage was unsuccessful, but the
client may make a second attempt, it returns the same HTTP status 401 response
as above, with the addition of the standard ``errcode`` and ``error`` fields
describing the error. For example:
.. code::
HTTP/1.1 401 Unauthorized
Content-Type: application/json
{
"errcode": "M_FORBIDDEN",
"error": "Invalid password",
"completed": [ "example.type.foo" ],
"flows": [
{
"stages": [ "example.type.foo", "example.type.bar" ]
},
{
"stages": [ "example.type.foo", "example.type.baz" ]
}
],
"params": {
"example.type.baz": {
"example_key": "foobar"
}
},
"session": "xxxxxx"
}
If the request fails for a reason other than authentication, the server returns an error
message in the standard format. For example:
.. code::
@ -302,10 +345,6 @@ message in the standard format:
"error": "Something was wrong"
}
Individual stages may require more than one request to complete, in which case
the response will be as if the request was unauthenticated with the addition of
any other keys as defined by the auth type.
If the client has completed all stages of a flow, the homeserver performs the
API call and returns the result as normal.
@ -389,7 +428,8 @@ To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.password",
"user": "<user_id or user localpart>",
"password": "<password>"
"password": "<password>",
"session": "<session ID>"
}
Alternatively reply using a 3pid bound to the user's account on the homeserver
@ -402,18 +442,13 @@ follows:
"type": "m.login.password",
"medium": "<The medium of the third party identifier. Must be 'email'>",
"address": "<The third party address of the user>",
"password": "<password>"
"password": "<password>",
"session": "<session ID>"
}
In the case that the homeserver does not know about the supplied 3pid, the
homeserver must respond with 403 Forbidden.
.. WARNING::
Clients SHOULD enforce that the password provided is suitably complex. The
password SHOULD include a lower-case letter, an upper-case letter, a number
and a symbol and be at a minimum 8 characters in length. Servers MAY reject
weak passwords with an error code ``M_WEAK_PASSWORD``.
Google ReCaptcha
<<<<<<<<<<<<<<<<
:Type:
@ -427,7 +462,8 @@ To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.recaptcha",
"response": "<captcha response>"
"response": "<captcha response>",
"session": "<session ID>"
}
Token-based
@ -444,7 +480,8 @@ To use this authentication type, clients should submit an auth dict as follows:
{
"type": "m.login.token",
"token": "<token>",
"txn_id": "<client generated nonce>"
"txn_id": "<client generated nonce>",
"session": "<session ID>"
}
The ``nonce`` should be a random string generated by the client for the
@ -460,8 +497,8 @@ server side, as well as potentially invalidating the token completely once the
device has successfully logged in (e.g. when we receive a request from the
newly provisioned access_token).
The ``token`` must be a macaroon, with a caveat encoding the user id. There is
therefore no need for the client to submit a separate username.
The server must encode the user id in the ``token``. There is therefore no need
for the client to submit a separate username.
OAuth2-based
<<<<<<<<<<<<
@ -511,7 +548,8 @@ To use this authentication type, clients should submit an auth dict as follows:
"client_secret": "<identity server client secret>",
"id_server": "<url of identity server authed with, e.g. 'matrix.org:8090'>"
}
]
],
"session": "<session ID>"
}
Dummy Auth
@ -529,12 +567,13 @@ the type and session, if provided:
.. code:: json
{
"type": "m.login.dummy"
"type": "m.login.dummy",
"session": "<session ID>"
}
Fallback
<<<<<<<<
++++++++
Clients cannot be expected to be able to know how to process every single login
type. If a client does not know how to handle a given login type, it can direct
the user to a web browser with the URL of a fallback page which will allow the
@ -544,11 +583,93 @@ should open is::
/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/<auth type>/fallback/web?session=<session ID>
Where ``auth type`` is the type name of the stage it is attempting and
``session id`` is the ID of the session given by the homeserver.
``session ID`` is the ID of the session given by the homeserver.
This MUST return an HTML page which can perform this authentication stage. This
page must attempt to call the JavaScript function ``window.onAuthDone`` when
the authentication has been completed.
page must use the following JavaScript when the authentication has been
completed:
.. code:: javascript
if (window.onAuthDone) {
window.onAuthDone();
} else if (window.opener && window.opener.postMessage) {
window.opener.postMessage("authDone", "*");
}
This allows the client to either arrange for the global function ``onAuthDone``
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
a notification that the authentication stage has been completed.
Once a client receives the notificaton that the authentication stage has been
completed, it should resubmit the request with an auth dict with just the
session ID:
.. code:: json
{
"session": "<session ID>"
}
Example
<<<<<<<
A client webapp might use the following javascript to open a popup window which will
handle unknown login types:
.. code:: javascript
/**
* Arguments:
* homeserverUrl: the base url of the homeserver (eg "https://matrix.org")
*
* apiEndpoint: the API endpoint being used (eg
* "/_matrix/client/%CLIENT_MAJOR_VERSION%/account/password")
*
* loginType: the loginType being attempted (eg "m.login.recaptcha")
*
* sessionID: the session ID given by the homeserver in earlier requests
*
* onComplete: a callback which will be called with the results of the request
*/
function unknownLoginType(homeserverUrl, apiEndpoint, loginType, sessionID, onComplete) {
var popupWindow;
var eventListener = function(ev) {
// check it's the right message from the right place.
if (ev.data !== "authDone" || ev.origin !== homeserverUrl) {
return;
}
// close the popup
popupWindow.close();
window.removeEventListener("message", eventListener);
// repeat the request
var requestBody = {
auth: {
session: sessionID,
},
};
request({
method:'POST', url:apiEndpint, json:requestBody,
}, onComplete);
};
window.addEventListener("message", eventListener);
var url = homeserverUrl +
"/_matrix/client/%CLIENT_MAJOR_VERSION%/auth/" +
encodeURIComponent(loginType) +
"/fallback/web?session=" +
encodeURIComponent(sessionID);
popupWindow = window.open(url);
}
Login
~~~~~
@ -595,9 +716,9 @@ follows:
"token": "<login token>"
}
As with `token-based`_ interactive login, the ``token`` must be a macroon with
a caveat which includes the user id. In the case that the token is not valid, the
homeserver must respond with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``.
As with `token-based`_ interactive login, the ``token`` must encode the
user id. In the case that the token is not valid, the homeserver must respond
with ``403 Forbidden`` and an error code of ``M_FORBIDDEN``.
{{login_cs_http_api}}
@ -615,6 +736,8 @@ This returns an HTML and JavaScript page which can perform the entire login
process. The page will attempt to call the JavaScript function
``window.onLogin`` when login has been successfully completed.
.. _Registration:
Account registration and management
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -1230,6 +1353,9 @@ have to wait in milliseconds before they can try again.
homeserver come up with their own idea, causing totally unpredictable performance over
federated rooms?
.. References
.. _`macaroon`: http://research.google.com/pubs/pub41892.html
.. Links through the external API docs are below
.. =============================================
@ -1237,15 +1363,15 @@ have to wait in milliseconds before they can try again.
.. |/initialSync| replace:: ``/initialSync``
.. _/initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-initialsync
.. |/tokenrefresh| replace:: ``/tokenrefresh``
.. _/tokenrefresh: #post-matrix-client-%CLIENT_MAJOR_VERSION%-tokenrefresh
.. |/sync| replace:: ``/sync``
.. _/sync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-sync
.. |/events| replace:: ``/events``
.. _/events: #get-matrix-client-%CLIENT_MAJOR_VERSION%-events
.. |/createRoom| replace:: ``/createRoom``
.. _/createRoom: #post-matrix-client-%CLIENT_MAJOR_VERSION%-createroom
.. |/rooms/<room_id>/initialSync| replace:: ``/rooms/<room_id>/initialSync``
.. _/rooms/<room_id>/initialSync: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-initialsync
@ -1258,6 +1384,9 @@ have to wait in milliseconds before they can try again.
.. |/rooms/<room_id>/state| replace:: ``/rooms/<room_id>/state``
.. _/rooms/<room_id>/state: #get-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-state
.. |/rooms/<room_id>/send| replace:: ``/rooms/<room_id>/send``
.. _/rooms/<room_id>/send: #put-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-send-eventtype-txnid
.. |/rooms/<room_id>/invite| replace:: ``/rooms/<room_id>/invite``
.. _/rooms/<room_id>/invite: #post-matrix-client-%CLIENT_MAJOR_VERSION%-rooms-roomid-invite
@ -1278,3 +1407,6 @@ have to wait in milliseconds before they can try again.
.. |/account/3pid| replace:: ``/account/3pid``
.. _/account/3pid: #post-matrix-client-%CLIENT_MAJOR_VERSION%-account-3pid
.. |/user/<user_id>/account_data/<type>| replace:: ``/user/<user_id>/account_data/<type>``
.. _/user/<user_id>/account_data/<type>: #put-matrix-client-%CLIENT_MAJOR_VERSION%-user-userid-account-data-type

@ -110,7 +110,7 @@ Creating a session
A client makes a call to::
POST https://my.id.server:8090/_matrix/identity/v1/api/validate/email/requestToken
POST https://my.id.server:8090/_matrix/identity/api/v1/validate/email/requestToken
client_secret=monkeys_are_GREAT&
email=foo@bar.com&
@ -147,7 +147,7 @@ Validating ownership of an email
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A user may make either a ``GET`` or a ``POST`` request to
``/_matrix/identity/v1/api/validate/email/submitToken`` with the following
``/_matrix/identity/api/v1/validate/email/submitToken`` with the following
parameters (either as query parameters or URL-encoded POST parameters):
- ``sid`` the sid for the session, generated by the ``requestToken`` call.
- ``client_secret`` the client secret which was supplied to the ``requestToken`` call.
@ -164,7 +164,7 @@ Checking non-published 3pid ownership
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
A client can check whether ownership of a 3pid was validated by making an
HTTP GET request to ``/_matrix/identity/v1/api/3pid/getValidated3pid``, passing
HTTP GET request to ``/_matrix/identity/api/v1/3pid/getValidated3pid``, passing
the ``sid`` and ``client_secret`` as query parameters from the ``requestToken``
call.
@ -183,7 +183,7 @@ Publishing a validated association
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
An association between a session and a Matrix user ID can be published by making
a URL-encoded HTTP POST request to ``/_matrix/identity/v1/api/3pid/bind`` with
a URL-encoded HTTP POST request to ``/_matrix/identity/api/v1/3pid/bind`` with
the following parameters::
sid=sid&
@ -256,7 +256,7 @@ At a later point, if the owner of that particular 3pid binds it with a Matrix us
Where the signature is produced using a long-term private key.
Also, the generated ephemeral public key will be listed as valid on requests to ``/_matrix/identity/v1/api/pubkey/ephemeral/isvalid``.
Also, the generated ephemeral public key will be listed as valid on requests to ``/_matrix/identity/api/v1/pubkey/ephemeral/isvalid``.
Ephemeral invitation signing
----------------------------

@ -0,0 +1,58 @@
.. Copyright 2016 OpenMarket Ltd
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
.. You may obtain a copy of the License at
..
.. http://www.apache.org/licenses/LICENSE-2.0
..
.. Unless required by applicable law or agreed to in writing, software
.. distributed under the License is distributed on an "AS IS" BASIS,
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
.. See the License for the specific language governing permissions and
.. limitations under the License.
Direct Messaging
================
.. _module:dm:
All communication over Matrix happens within a room. It is sometimes
desirable to offer users the concept of speaking directly to one
particular person. This module defines a way of marking certain rooms
as 'direct chats' with a given person. This does not restrict the chat
to being between exactly two people since this would preclude the
presence of automated 'bot' users or even a 'personal assistant' who is
able to answer direct messages on behalf of the user in their absence.
A room may not necessarily be considered 'direct' by all members of the
room, but a signalling mechanism exists to propagate the information of
whether a chat is 'direct' to an invitee.
Events
------
{{m_direct_event}}
Client behaviour
----------------
To start a direct chat with another user, the inviting user's client
should set the ``is_direct`` flag to |/createRoom|_. The client should do
this whenever the flow the user has followed is one where their
intention is to speak directly with another person, as opposed to bringing that
person in to a shared room. For example, clicking on 'Start Chat' beside a
person's profile picture would imply the ``is_direct`` flag should be set.
The invitee's client may use the ``is_direct`` flag in the `m.room.member`_
event to automatically mark the room as a direct chat but this is not
required: it may for example, prompt the user, or ignore the flag altogether.
Both the inviting client and the invitee's client should record the fact that
the room is a direct chat by storing an ``m.direct`` event in the account data
using |/user/<user_id>/account_data/<type>|_.
Server behaviour
----------------
When the ``is_direct`` flag is given to |/createRoom|_, the home
server must set the ``is_direct`` flag in the invite member event for any users
invited in the |/createRoom|_ call.

@ -107,6 +107,15 @@ There is a single API endpoint for this, as described below.
.. _pushers: `def:pushers`_
Listing Notifications
~~~~~~~~~~~~~~~~~~~~~
A client can retrieve a list of events that it has been notified about. This
may be useful so that users can see a summary of what important messages they
have received.
{{notifications_cs_http_api}}
Push Rules
~~~~~~~~~~
A push rule is a single rule that states under what *conditions* an event should

@ -0,0 +1,146 @@
.. Copyright 2016 OpenMarket Ltd
..
.. Licensed under the Apache License, Version 2.0 (the "License");
.. you may not use this file except in compliance with the License.
.. You may obtain a copy of the License at
..
.. http://www.apache.org/licenses/LICENSE-2.0
..
.. Unless required by applicable law or agreed to in writing, software
.. distributed under the License is distributed on an "AS IS" BASIS,
.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
.. See the License for the specific language governing permissions and
.. limitations under the License.
Send-to-Device messaging
========================
.. _module:to_device:
This module provides a means by which clients can exchange signalling messages
without them being stored permanently as part of a shared communication
history. A message is delivered exactly once to each client device.
The primary motivation for this API is exchanging data that is meaningless or
undesirable to persist in the room DAG - for example, one-time authentication
tokens or key data. It is not intended for conversational data, which should be
sent using the normal |/rooms/<room_id>/send|_ API for consistency throughout
Matrix.
Client behaviour
----------------
To send a message to other devices, a client should call |/sendToDevice|_.
Only one message can be sent to each device per transaction, and they must all
have the same event type. The device ID in the request body can be set to ``*``
to request that the message be sent to all known devices.
If there are send-to-device messages waiting for a client, they will be
returned by |/sync|_, as detailed in `Extensions to /sync`_. Clients should
inspect the ``type`` of each returned event, and ignore any they do not
understand.
Server behaviour
----------------
Servers should store pending messages for local users until they are
successfully delivered to the destination device. When a client calls |/sync|_
with an access token which corresponds to a device with pending messages, the
server should list the pending messages, in order of arrival, in the response
body.
When the client calls ``/sync`` again with the ``next_batch`` token from the
first response, the server should infer that any send-to-device messages in
that response have been delivered successfully, and delete them from the store.
If there is a large queue of send-to-device messages, the server should
limit the number sent in each ``/sync`` response. 100 messages is recommended
as a reasonable limit.
If the client sends messages to users on remote domains, those messages should
be sent on to the remote servers via
`federation`_.
.. _`federation`: ../server_server/latest.html#send-to-device-messages
.. TODO-spec:
* Is a server allowed to delete undelivered messages? After how long? What
about if the device is deleted?
* If the destination HS doesn't support the ``m.direct_to_device`` EDU, it
will just get dumped. Should we indicate that to the client?
Protocol definitions
--------------------
{{to_device_cs_http_api}}
.. TODO-spec:
* What should a server do if the user id or device id is unknown? Presumably
it shouldn't reject the request outright, because some of the destinations
may be valid. Should we add something to the response?
.. anchor for link from /sync api spec
.. |send_to_device_sync| replace:: Send-to-Device messaging
.. _send_to_device_sync:
Extensions to /sync
~~~~~~~~~~~~~~~~~~~
This module adds the following properties to the |/sync|_ response:
.. todo: generate this from a swagger definition?
========= ========= =======================================================
Parameter Type Description
========= ========= =======================================================
to_device ToDevice Optional. Information on the send-to-device messages
for the client device.
========= ========= =======================================================
``ToDevice``
========= ========= =============================================
Parameter Type Description
========= ========= =============================================
events [Event] List of send-to-device messages
========= ========= =============================================
``Event``
================ ============ ==================================================
Parameter Type Description
================ ============ ==================================================
content EventContent The content of this event. The fields in this
object will vary depending on the type of event.
sender string The Matrix user ID of the user who sent this
event.
type string The type of event.
================ ============ ==================================================
Example response:
.. code:: json
{
"next_batch": "s72595_4483_1934",
"rooms": {"leave": {}, "join": {}, "invite": {}},
"to_device": {
"events": [
{
"sender": "@alice:example.com",
"type": "m.new_device",
"content": {
"device_id": "XYZABCDE",
"rooms": ["!726s6s6q:example.com"]
}
}
]
}
}
.. |/sendToDevice| replace:: ``/sendToDevice``
.. _/sendToDevice: #put-matrix-client-%CLIENT_MAJOR_VERSION%-sendtodevice-eventtype-txnid

@ -974,3 +974,27 @@ The list of join candidates is a list of server names that are likely to hold
the given room; these are servers that the requesting server may wish to use as
resident servers as part of the remote join handshake. This list may or may not
include the server answering the query.
Send-to-device messaging
------------------------
.. TODO: add modules to the federation spec and make this a module
The server API for send-to-device messaging is based on the following
EDU. There are no PDUs or Federation Queries involved.
Each send-to-device message should be sent to the destination server using
the following EDU::
EDU type: m.direct_to_device
Content keys:
sender: user ID of the sender
type: event type for the message
message_id: unique id for the message: used for idempotence
messages: The messages to send. A map from user ID, to a map from device ID
to message body. The device ID may also be *, meaning all known devices
for the user.

@ -41,6 +41,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
- modules/receipts.rst
- modules/presence.rst
- modules/content_repo.rst
- modules/send_to_device.rst
- modules/end_to_end_encryption.rst
- modules/history_visibility.rst
- modules/push.rst
@ -53,6 +54,7 @@ groups: # reusable blobs of files when prefixed with 'group:'
- modules/admin.rst
- modules/event_context.rst
- modules/cas_login.rst
- modules/dm.rst
title_styles: ["=", "-", "~", "+", "^", "`", "@", ":"]

@ -5,7 +5,7 @@ categories: projects client
thumbnail: https://matrix.org/blog/wp-content/uploads/2015/08/vector030216-400x284.png
author: Riot.im
description: Riot is a glossy web client with an emphasis on performance and usability
maturity: Late beta
maturity: Released
---
![screenshot](https://matrix.org/blog/wp-content/uploads/2015/08/vector030216-1080x745.png "{{ page.title }}")

@ -1,7 +1,6 @@
---
layout: project
title: Try Matrix Now!
categories: projects client
---
<html>

@ -5,7 +5,7 @@ categories: projects client
thumbnail: /docs/projects/images/vector-iOS-small.png
description: Riot is a glossy client with an emphasis on performance and usability
author: Riot.im
maturity: Beta
maturity: Released
---
![screenshot](/docs/projects/images/vector-iOS-large.png "{{ page.title }}")

@ -1,7 +1,6 @@
---
layout: project
title: Try Matrix Now!
categories: projects client
---
<html>

@ -5,7 +5,7 @@ categories: projects client
thumbnail: /docs/projects/images/vector-android-small.png
description: Riot is a glossy client with an emphasis on performance and usability
author: Riot.im
maturity: Beta
maturity: Released
---
![screenshot](/docs/projects/images/vector-android-large.png "{{ page.title }}")
@ -13,6 +13,6 @@ maturity: Beta
# {{ page.title }}
The Android version of the [Riot](https://matrix.org/docs/projects/client/riot.html) web client. Riot is a glossy client with focus on performance and usability.
The code is available from [github](https://github.com/vector-im/vector-android), and the app is available from the [Google Play store](https://play.google.com/store/apps/details?id=im.riot) and (as "Vector") [F-Droid](https://f-droid.org/repository/browse/?fdfilter=vector&fdid=im.vector.alpha).
The code is available from [github](https://github.com/vector-im/vector-android), and the app is available from the [Google Play store](https://play.google.com/store/apps/details?id=im.vector.alpha) and [F-Droid](https://f-droid.org/repository/browse/?fdfilter=vector&fdid=im.vector.alpha).
If you want to help test the app, you can download development versions from [Jenkins](https://matrix.org/jenkins/job/VectorAndroidDevelop/).

@ -1,7 +1,6 @@
---
layout: project
title: Try Matrix Now!
categories: projects client
---
<html>

@ -0,0 +1,13 @@
---
layout: project
title: MatrixTool
categories: projects other
description: Commands to interact with a Matrix homeserver
author: LeoNerd
maturity: Alpha
---
# {{ page.title }}
The tool provides a wrapper around a number of sub-commands that provide useful interactions with a Matrix homeserver.
You can grab it from [CPAN](http://search.cpan.org/~pevans/App-MatrixTool/).

@ -1,7 +1,6 @@
---
layout: project
title: Vector Desktop
categories: projects client
description: Desktop version of Vector
author: Steven Hammerton
maturity: Alpha

@ -0,0 +1,12 @@
---
layout: project
title: telematrix
categories: projects as
author: SijmenSchoon
maturity: Alpha
---
# {{ page.title }}
This project bridges [Telegram Messenger](https://telegram.org/) to Matrix. It's currently in early development, and not considered to be in a usable state yet.
Get it and report issues at [github](https://github.com/SijmenSchoon/telematrix)!

@ -96,8 +96,7 @@ def inherit_parents(obj):
return result
def get_json_schema_object_fields(obj, enforce_title=False,
mark_required=True):
def get_json_schema_object_fields(obj, enforce_title=False):
# Algorithm:
# f.e. property => add field info (if field is object then recurse)
if obj.get("type") != "object":
@ -175,8 +174,7 @@ def get_json_schema_object_fields(obj, enforce_title=False,
try:
logger.debug("Processing property %s.%s", obj_title, key_name)
required = key_name in required_keys
res = process_prop(key_name, props[key_name], required,
mark_required)
res = process_prop(key_name, props[key_name], required)
first_table_rows.append(res["row"])
tables.extend(res["tables"])
@ -196,7 +194,7 @@ def get_json_schema_object_fields(obj, enforce_title=False,
return tables
def process_prop(key_name, prop, required, mark_required):
def process_prop(key_name, prop, required):
prop = inherit_parents(prop)
value_type = None
@ -213,7 +211,6 @@ def process_prop(key_name, prop, required, mark_required):
nested_objects = get_json_schema_object_fields(
prop,
enforce_title=True,
mark_required=mark_required,
)
value_type = nested_objects[0]["title"]
value_id = value_type
@ -226,7 +223,6 @@ def process_prop(key_name, prop, required, mark_required):
nested_objects = get_json_schema_object_fields(
items,
enforce_title=True,
mark_required=mark_required,
)
value_id = nested_objects[0]["title"]
value_type = "[%s]" % value_id
@ -269,7 +265,7 @@ def process_prop(key_name, prop, required, mark_required):
value_type = " or ".join(value_type)
if required and mark_required:
if required:
desc = "**Required.** " + desc
return {
@ -284,10 +280,9 @@ def process_prop(key_name, prop, required, mark_required):
}
def get_tables_for_schema(schema, mark_required=True):
def get_tables_for_schema(schema):
schema = inherit_parents(schema)
tables = get_json_schema_object_fields(schema,
mark_required=mark_required)
tables = get_json_schema_object_fields(schema)
# the result may contain duplicates, if objects are referred to more than
# once. Filter them out.
@ -470,9 +465,7 @@ class MatrixUnits(Units):
elif res_type and Units.prop(good_response, "schema/properties"):
# response is an object:
schema = good_response["schema"]
res_tables = get_tables_for_schema(schema,
mark_required=False,
)
res_tables = get_tables_for_schema(schema)
endpoint["res_tables"].extend(res_tables)
elif res_type and Units.prop(good_response, "schema/items"):
# response is an array:

Loading…
Cancel
Save