Matrix: no account can be made from here #165

Closed
opened 2026-09-10 15:45:12 -04:00 by Salastil · 1 comment
Owner

POST /_matrix/client/v3/register is not called anywhere, so adding a Matrix account
means already having one — made in Element or on a homeserver's own page. There is
also no OIDC/MSC3861 login path, which is the direction Matrix authentication is
moving and which some homeservers now require.

Both are the same shape of gap: the account has to exist elsewhere first.

What is needed

  • Registration through the existing UIA machinery (matrix/http.rs:155, :184),
    which already handles the interactive-auth stages a register flow uses.
  • OIDC would follow the pattern the browser sign-in window already sets
    (src/main/browser-login.ts) rather than needing anything new.

Done looks like: somebody with no Matrix account can get one without leaving moho.

`POST /_matrix/client/v3/register` is not called anywhere, so adding a Matrix account means already having one — made in Element or on a homeserver's own page. There is also no OIDC/MSC3861 login path, which is the direction Matrix authentication is moving and which some homeservers now require. Both are the same shape of gap: the account has to exist elsewhere first. **What is needed** - Registration through the existing UIA machinery (`matrix/http.rs:155`, `:184`), which already handles the interactive-auth stages a register flow uses. - OIDC would follow the pattern the browser sign-in window already sets (`src/main/browser-login.ts`) rather than needing anything new. **Done looks like:** somebody with no Matrix account can get one without leaving moho.
Salastil added the featureprotocollow priority labels 2026-09-10 15:45:12 -04:00
Salastil removed the protocol label 2026-09-10 15:53:26 -04:00
Author
Owner

Done in nobilis 898cd5c and moho a584d9a — with one half of the ticket reframed rather than built, explained below.

Registration is implemented. It is user-interactive auth, so the first attempt is expected to be refused: the server answers 401 with the stages it wants and a session to carry between them. That 401 is an answer rather than a failure, which needed its own POST helper — handle_response rightly treats a 401 as an error everywhere else, and doing so here discards the part of the reply that says how to continue.

What it completes is m.login.dummy, the stage that exists so a flow can have no stages, which is what an openly-registering homeserver asks for. Everything else is named rather than attempted: a captcha cannot be answered from here, an email or SMS stage needs a message read elsewhere, and terms need reading rather than agreeing to on somebody's behalf. The refusal says which the server wants and says to sign up on its own page.

Nothing is stored before it works, unlike the login path — a failed registration leaves no account to retry against, since the name may now be taken, by us, or not exist at all, and guessing which would be storing a guess.

On OIDC, and this is worth being precise about rather than quietly closing: moho already has m.login.sso with a loopback callback (start_sso_login), which is the browser-based path and covers homeservers that delegate to an OIDC provider — the common case today. What is not implemented is MSC3861 native OIDC, where a homeserver has no /login at all. That is a different and much larger piece of work, and no homeserver in use here needs it. If it becomes relevant it deserves its own ticket rather than sitting inside this one.

Done in nobilis [898cd5c](https://git.salastil.com/Salastil/nobilis/commit/898cd5c) and moho [a584d9a](https://git.salastil.com/Salastil/moho/commit/a584d9a) — with one half of the ticket reframed rather than built, explained below. **Registration** is implemented. It is user-interactive auth, so the first attempt is *expected* to be refused: the server answers 401 with the stages it wants and a session to carry between them. That 401 is an answer rather than a failure, which needed its own POST helper — `handle_response` rightly treats a 401 as an error everywhere else, and doing so here discards the part of the reply that says how to continue. What it completes is `m.login.dummy`, the stage that exists so a flow can have no stages, which is what an openly-registering homeserver asks for. Everything else is **named rather than attempted**: a captcha cannot be answered from here, an email or SMS stage needs a message read elsewhere, and terms need reading rather than agreeing to on somebody's behalf. The refusal says which the server wants and says to sign up on its own page. Nothing is stored before it works, unlike the login path — a failed registration leaves no account to retry against, since the name may now be taken, by us, or not exist at all, and guessing which would be storing a guess. **On OIDC**, and this is worth being precise about rather than quietly closing: moho already has `m.login.sso` with a loopback callback (`start_sso_login`), which is the browser-based path and covers homeservers that delegate to an OIDC provider — the common case today. What is *not* implemented is MSC3861 **native** OIDC, where a homeserver has no `/login` at all. That is a different and much larger piece of work, and no homeserver in use here needs it. If it becomes relevant it deserves its own ticket rather than sitting inside this one.
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Salastil/moho#165