element-android/docs/signup.md
2022-05-30 14:35:11 +02:00

15 KiB

Sign up to a homeserver

This document describes the flow of registration to a homeserver. Examples come from the matrix.org homeserver.

Ref: https://matrix.org/docs/spec/client_server/latest#account-registration-and-management

Sign up flows

First step

Client request the sign-up flows, once the homeserver is chosen by the user and its url is known (in the example it's https://matrix.org)

curl -X POST --data $'{}' 'https://matrix.org/_matrix/client/r0/register'
{
}

We get the flows with a 401, which also means that the registration is possible on this homeserver.

{
  "session": "vwehdKMtkRedactedAMwgCACZ",
  "flows": [
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.dummy"
      ]
    },
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.email.identity"
      ]
    }
  ],
  "params": {
    "m.login.recaptcha": {
      "public_key": "6LcgI54UAAAAAoREDACTEDoDdOocFpYVdjYBRe4zb"
    },
    "m.login.terms": {
      "policies": {
        "privacy_policy": {
          "version": "1.0",
          "en": {
            "name": "Terms and Conditions",
            "url": "https:\/\/matrix.org\/_matrix\/consent?v=1.0"
          }
        }
      }
    }
  }
}

If the registration is not possible, we get a 403

{
  "errcode": "M_FORBIDDEN",
  "error": "Registration is disabled"
}

Step 1: entering user name and password

The app is displaying a form to enter username and password.

curl -X POST --data $'{"initial_device_display_name":"Mobile device","username":"alice","password": "weak_password"}' 'https://matrix.org/_matrix/client/r0/register'
{
  "initial_device_display_name": "Mobile device",
  "username": "alice",
  "password": "weak_password"
}
  1. Note that the session value has changed (because we did not provide the previous value in the request body), but it's ok, we will use the new value for the next steps.
{
  "session": "xptUYoREDACTEDogOWAGVnbJQ",
  "flows": [
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.dummy"
      ]
    },
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.email.identity"
      ]
    }
  ],
  "params": {
    "m.login.recaptcha": {
      "public_key": "6LcgI54UAAAAAoREDACTEDoDdOocFpYVdjYBRe4zb"
    },
    "m.login.terms": {
      "policies": {
        "privacy_policy": {
          "version": "1.0",
          "en": {
            "name": "Terms and Conditions",
            "url": "https:\/\/matrix.org\/_matrix\/consent?v=1.0"
          }
        }
      }
    }
  }
}

If username already exists

We get a 400:

{
  "errcode": "M_USER_IN_USE",
  "error": "User ID already taken."
}

Step 2: entering email

User is proposed to enter an email. User skips this step.

curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.dummy"}}' 'https://matrix.org/_matrix/client/r0/register'
{
  "auth": {
    "session": "xptUYoREDACTEDogOWAGVnbJQ",
    "type": "m.login.dummy"
  }
}

401

{
  "session": "xptUYoREDACTEDogOWAGVnbJQ",
  "flows": [
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.dummy"
      ]
    },
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.email.identity"
      ]
    }
  ],
  "params": {
    "m.login.recaptcha": {
      "public_key": "6LcgI54UAAAAAoREDACTEDoDdOocFpYVdjYBRe4zb"
    },
    "m.login.terms": {
      "policies": {
        "privacy_policy": {
          "version": "1.0",
          "en": {
            "name": "Terms and Conditions",
            "url": "https:\/\/matrix.org\/_matrix\/consent?v=1.0"
          }
        }
      }
    }
  },
  "completed": [
    "m.login.dummy"
  ]
}

Step 2 bis: user enters an email

We request a token to the homeserver. The client_secret is generated by the application

curl -X POST --data $'{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","email":"alice@email-provider.org","send_attempt":0}' 'https://matrix.org/_matrix/client/r0/register/email/requestToken'
{
  "client_secret": "53e679ea-oRED-ACTED-92b8-3012c49c6cfa",
  "email": "alice@email-provider.org",
  "send_attempt": 0
}

200

{
  "sid": "qlBCREDACTEDEtgxD"
}

And

curl -X POST --data $'{"auth":{"threepid_creds":{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","sid":"qlBCREDACTEDEtgxD"},"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.email.identity"}}' 'https://matrix.org/_matrix/client/r0/register'
{
  "auth": {
    "threepid_creds": {
      "client_secret": "53e679ea-oRED-ACTED-92b8-3012c49c6cfa",
      "sid": "qlBCREDACTEDEtgxD"
    },
    "session": "xptUYoREDACTEDogOWAGVnbJQ",
    "type": "m.login.email.identity"
  }
}

We get 401 since the email is not validated yet:

{
  "errcode": "M_UNAUTHORIZED",
  "error": ""
}

The app is now polling on

curl -X POST --data $'{"auth":{"threepid_creds":{"client_secret":"53e679ea-oRED-ACTED-92b8-3012c49c6cfa","sid":"qlBCREDACTEDEtgxD"},"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.email.identity"}}' 'https://matrix.org/_matrix/client/r0/register'
{
  "auth": {
    "threepid_creds": {
      "client_secret": "53e679ea-oRED-ACTED-92b8-3012c49c6cfa",
      "sid": "qlBCREDACTEDEtgxD"
    },
    "session": "xptUYoREDACTEDogOWAGVnbJQ",
    "type": "m.login.email.identity"
  }
}

User clicks on the link received by email https://matrix.org/_matrix/client/unstable/registration/email/submit_token?token=vtQjQIZfwdoREDACTEDozrmKYSWlCXsJ&client_secret=53e679ea-oRED-ACTED-92b8-3012c49c6cfa&sid=qlBCREDACTEDEtgxD which contains:

  • A token vtQjQIZfwdoREDACTEDozrmKYSWlCXsJ
  • The client_secret: 53e679ea-oRED-ACTED-92b8-3012c49c6cfa
  • A sid: qlBCREDACTEDEtgxD

Once the link is clicked, the registration request (polling) returns a 401 with the following content:

{
  "session": "xptUYoREDACTEDogOWAGVnbJQ",
  "flows": [
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.dummy"
      ]
    },
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.email.identity"
      ]
    }
  ],
  "params": {
    "m.login.recaptcha": {
      "public_key": "6LcgI54UAAAAAoREDACTEDoDdOocFpYVdjYBRe4zb"
    },
    "m.login.terms": {
      "policies": {
        "privacy_policy": {
          "version": "1.0",
          "en": {
            "name": "Terms and Conditions",
            "url": "https:\/\/matrix.org\/_matrix\/consent?v=1.0"
          }
        }
      }
    }
  },
  "completed": [
    "m.login.email.identity"
  ]
}

Step 3: Accepting T&C

User is proposed to accept T&C and he accepts them

curl -X POST --data $'{"auth":{"session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.terms"}}' 'https://matrix.org/_matrix/client/r0/register'
{
  "auth": {
    "session": "xptUYoREDACTEDogOWAGVnbJQ",
    "type": "m.login.terms"
  }
}

401

{
  "session": "xptUYoREDACTEDogOWAGVnbJQ",
  "flows": [
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.dummy"
      ]
    },
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.email.identity"
      ]
    }
  ],
  "params": {
    "m.login.recaptcha": {
      "public_key": "6LcgI54UAAAAAoREDACTEDoDdOocFpYVdjYBRe4zb"
    },
    "m.login.terms": {
      "policies": {
        "privacy_policy": {
          "version": "1.0",
          "en": {
            "name": "Terms and Conditions",
            "url": "https:\/\/matrix.org\/_matrix\/consent?v=1.0"
          }
        }
      }
    }
  },
  "completed": [
    "m.login.dummy",
    "m.login.terms"
  ]
}

Step 4: Captcha

User is proposed to prove he is not a robot and he does it:

curl -X POST --data $'{"auth":{"response":"03AOLTBLSiGS9GhFDpAMblJ2nlXOmHXqAYJ5OvHCPUjiVLBef3k9snOYI_BDC32-t4D2jv-tpvkaiEI_uloobFd9RUTPpJ7con2hMddbKjSCYqXqcUQFhzhbcX6kw8uBnh2sbwBe80_ihrHGXEoACXQkL0ki1Q0uEtOeW20YBRjbNABsZPpLNZhGIWC0QVXnQ4FouAtZrl3gOAiyM-oG3cgP6M9pcANIAC_7T2P2amAHbtsTlSR9CsazNyS-rtDR9b5MywdtnWN9Aw8fTJb8cXQk_j7nvugMxzofPjSOrPKcr8h5OqPlpUCyxxnFtag6cuaPSUwh43D2L0E-ZX7djzaY2Yh_U2n6HegFNPOQ22CJmfrKwDlodmAfMPvAXyq77n3HpoREDACTEDo3830RHF4BfkGXUaZjctgg-A1mvC17hmQmQpkG7IhDqyw0onU-0vF_-ehCjq_CcQEDpS_O3uiHJaG5xGf-0rhLm57v_wA3deugbsZuO4uTuxZZycN_mKxZ97jlDVBetl9hc_5REPbhcT1w3uzTCSx7Q","session":"xptUYoREDACTEDogOWAGVnbJQ","type":"m.login.recaptcha"}}' 'https://matrix.org/_matrix/client/r0/register'
{
  "auth": {
    "response": "03AOLTBLSiGS9GhFDpAMblJ2nlXOmHXqAYJ5OvHCPUjiVLBef3k9snOYI_BDC32-t4D2jv-tpvkaiEI_uloobFd9RUTPpJ7con2hMddbKjSCYqXqcUQFhzhbcX6kw8uBnh2sbwBe80_ihrHGXEoACXQkL0ki1Q0uEtOeW20YBRjbNABsZPpLNZhGIWC0QVXnQ4FouAtZrl3gOAiyM-oG3cgP6M9pcANIAC_7T2P2amAHbtsTlSR9CsazNyS-rtDR9b5MywdtnWN9Aw8fTJb8cXQk_j7nvugMxzofPjSOrPKcr8h5OqPlpUCyxxnFtag6cuaPSUwh43D2L0E-ZX7djzaY2Yh_U2n6HegFNPOQ22CJmfrKwDlodmAfMPvAXyq77n3HpoREDACTEDo3830RHF4BfkGXUaZjctgg-A1mvC17hmQmQpkG7IhDqyw0onU-0vF_-ehCjq_CcQEDpS_O3uiHJaG5xGf-0rhLm57v_wA3deugbsZuO4uTuxZZycN_mKxZ97jlDVBetl9hc_5REPbhcT1w3uzTCSx7Q",
    "session": "xptUYoREDACTEDogOWAGVnbJQ",
    "type": "m.login.recaptcha"
  }
}

200

{
  "user_id": "@alice:matrix.org",
  "home_server": "matrix.org",
  "access_token": "MDAxOGxvY2F0aW9uIG1hdHJpeC5vcmcKMoREDACTEDo50aWZpZXIga2V5CjAwMTBjaWQgZ2VuID0gMQowMDI5Y2lkIHVzZXJfaWQgPSBAYmVub2l0eHh4eDptYXRoREDACTEDoCjAwMTZjaWQgdHlwZSA9IGFjY2VzcwowMDIxY2lkIG5vbmNlID0gNHVSVm00aVFDaWlKdoREDACTEDoJmc2lnbmF0dXJlIOmHnTLRfxiPjhrWhS-dThUX-qAzZktfRThzH1YyAsxaCg",
  "device_id": "FLBAREDAJZ"
}

The account is created!

Step 5: MSISDN

Some homeservers may require the user to enter MSISDN.

On matrix.org, it's not required, and not even optional, but it's still possible for the app to add a MSISDN during the registration.

The user enters a phone number and selects a country, the client_secret is generated by the application

curl -X POST --data $'{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","send_attempt":1,"country":"FR","phone_number":"+33611223344"}'  'https://matrix.org/_matrix/client/r0/register/msisdn/requestToken'
{
  "client_secret": "d3e285f6-972a-496c-9a22-7915a2db57c7",
  "send_attempt": 1,
  "country": "FR",
  "phone_number": "+33611223344"
}

If the msisdn is already associated to another account, you will received an error:

{
  "errcode": "M_THREEPID_IN_USE",
  "error": "Phone number is already in use"
}

If it is not the case, the homeserver send the SMS and returns some data, especially a sid and a submit_url:

{
  "msisdn": "33611223344",
  "intl_fmt": "+336 11 22 33 44",
  "success": true,
  "sid": "1678881798",
  "submit_url": "https:\/\/matrix.org\/_matrix\/client\/unstable\/add_threepid\/msisdn\/submit_token"
}

When we execute the register request, with the received sid, we get an error since the MSISDN is not validated yet:

curl -X POST --data $'{"auth":{"type":"m.login.msisdn","session":"xptUYoREDACTEDogOWAGVnbJQ","threepid_creds":{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798"}}}' 'https://matrix.org/_matrix/client/r0/register'
  "auth": {
    "type": "m.login.msisdn",
    "session": "xptUYoREDACTEDogOWAGVnbJQ",
    "threepid_creds": {
      "client_secret": "d3e285f6-972a-496c-9a22-7915a2db57c7",
      "sid": "1678881798"
    }
  }
}

There is an issue on Synapse, which return a 401, it sends too much data along with the classical MatrixError fields:

{
  "session": "xptUYoREDACTEDogOWAGVnbJQ",
  "flows": [
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.dummy"
      ]
    },
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.email.identity"
      ]
    }
  ],
  "params": {
    "m.login.recaptcha": {
      "public_key": "6LcgI54UAAAAABGdGmruw6DdOocFpYVdjYBRe4zb"
    },
    "m.login.terms": {
      "policies": {
        "privacy_policy": {
          "version": "1.0",
          "en": {
            "name": "Terms and Conditions",
            "url": "https:\/\/matrix.org\/_matrix\/consent?v=1.0"
          }
        }
      }
    }
  },
  "completed": [],
  "error": "",
  "errcode": "M_UNAUTHORIZED"
}

The user receive the SMS, he can enter the SMS code in the app, which is sent using the "submit_url" received ie the response of the requestToken request:

curl -X POST --data $'{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798","token":"123456"}' 'https://matrix.org/_matrix/client/unstable/add_threepid/msisdn/submit_token'
{
  "client_secret": "d3e285f6-972a-496c-9a22-7915a2db57c7",
  "sid": "1678881798",
  "token": "123456"
}

If the code is not correct, we get a 200 with:

{
  "success": false
}

And if the code is correct we get a 200 with:

{
  "success": true
}

We can now execute the registration request, to the homeserver

curl -X POST --data $'{"auth":{"type":"m.login.msisdn","session":"xptUYoREDACTEDogOWAGVnbJQ","threepid_creds":{"client_secret":"d3e285f6-972a-496c-9a22-7915a2db57c7","sid":"1678881798"}}}' 'https://matrix.org/_matrix/client/r0/register'
{
  "auth": {
    "type": "m.login.msisdn",
    "session": "xptUYoREDACTEDogOWAGVnbJQ",
    "threepid_creds": {
      "client_secret": "d3e285f6-972a-496c-9a22-7915a2db57c7",
      "sid": "1678881798"
    }
  }
}

Now the homeserver considers that the m.login.msisdn step is completed (401):

{
  "session": "xptUYoREDACTEDogOWAGVnbJQ",
  "flows": [
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.dummy"
      ]
    },
    {
      "stages": [
        "m.login.recaptcha",
        "m.login.terms",
        "m.login.email.identity"
      ]
    }
  ],
  "params": {
    "m.login.recaptcha": {
      "public_key": "6LcgI54UAAAAABGdGmruw6DdOocFpYVdjYBRe4zb"
    },
    "m.login.terms": {
      "policies": {
        "privacy_policy": {
          "version": "1.0",
          "en": {
            "name": "Terms and Conditions",
            "url": "https:\/\/matrix.org\/_matrix\/consent?v=1.0"
          }
        }
      }
    }
  },
  "completed": [
    "m.login.msisdn"
  ]
}