diff --git a/proposals/4031-pre-generate-invites.md b/proposals/4031-pre-generate-invites.md index 11ff9de01..2f6b766b0 100644 --- a/proposals/4031-pre-generate-invites.md +++ b/proposals/4031-pre-generate-invites.md @@ -3,7 +3,9 @@ ## Introduction -Currently, onboarding users to the Matrix Fediverse has more points of friction than its peers. The timeline for an existing Matrix user to on-board a new user to their space, and/or room by extension, is significantly longer than what it could be from the invitee's perspective: +Currently, onboarding users to the Matrix Fediverse has more points of friction than its peers. The timeline +for an existing Matrix user to on-board a new user to their space, and/or room by extension, is significantly +longer than what it could be from the invitee's perspective: > 1. Ask friend to join matrix/homeserver @@ -20,7 +22,9 @@ Versus the flow for onboarding an invitee in other services, and what this MSC a > 3. Hand them invite code/link > 4. They join your room/space -Where in the improved flow, there is no necessity for exessive back-and-forth between the inviter and invitee. With pre-generated invites, points 1 and 3 could realistically be condensed into a single event from the invitee's point of view. +Where in the improved flow, there is no necessity for exessive back-and-forth between the inviter and invitee. +With pre-generated invites, points 1 and 3 could realistically be condensed into a single event from the invitee's +point of view. ## Proposal @@ -70,16 +74,21 @@ Example: This example is using a sha-265 hash of the string `inviteme!` for the hash. -A user attempted to join a room via providing a secret will have it hashed and compared against the stored hash to determine if they may use the specific invite room event to join. +A user attempted to join a room via providing a secret will have it hashed and compared against the stored hash +to determine if they may use the specific invite room event to join. -The burden of remembering the secret key will be on the person who created the invite, however this is acceptable as clients could generate an extended room ID with the state key and provided/generated secret. +The burden of remembering the secret key will be on the person who created the invite, however this is acceptable +as clients could generate an extended room ID with the state key and provided/generated secret. ### Extend the room URI when using inline invite keys Currently room uris take the form of `[string]:[server_name]`, and they could be extended to: -`[string]:[server_name]#[state_key]/[secret_key]` so that a client can interpret the state and secret keys from the URI and allow a join request to be made with the identifying information needed for the homeserver to add the user to the room's member list. -Optionally clients could also ask a user for a state_key and secret key when one or both is not provided, and the room they are are attempting to join is rejecting their join request. +`[string]:[server_name]#[state_key]/[secret_key]` so that a client can interpret the state and secret keys +from the URI and allow a join request to be made with the identifying information needed for the homeserver +to add the user to the room's member list. +Optionally clients could also ask a user for a state_key and secret key when one or both is not provided, +and the room they are are attempting to join is rejecting their join request. For example, the following invite URI could be generated by a user's client: @@ -88,9 +97,10 @@ For example, the following invite URI could be generated by a user's client: ``` and subsequently handed over to a https://matrix.to or equivalent redirection service to create clickable links such as: -[`https://matrix.to/#/!irs2iosct:example.com#MwhqK12Rs4/inviteme!`](https://matrix.to/#/!irs2iosct:example.com#MwhqK12Rs4/inviteme!) (This link goes nowhere) +https://matrix.to/#/!irs2iosct:example.com#MwhqK12Rs4/inviteme! -While not as pretty as some of Matrix's peers' invite urls, it would fulfill the basic function of allowing a user to join a private room without have their specific user account explicitly invited to participate. +While not as pretty as some of Matrix's peers' invite urls, it would fulfill the basic function of allowing a +user to join a private room without have their specific user account explicitly invited to participate. ### Extend the `m.room.power_levels` state event @@ -105,14 +115,20 @@ Add new content items for managing and creating invites. ### New API endpoints to get room invites -Ideally, invites *should not* be exposed by the [`/_matrix/client/v3/rooms/{roomId}/state`](https://spec.matrix.org/v1.7/client-server-api/#get_matrixclientv3roomsroomidstate) endpoint *unless* the requesting user has the power level required to list invites. Any invites created by the requesting user *should* be returned, regardless of the user's power level. It is assumed that a user with invites has, or had the power level required to create their own invites, so they should remain accessible to them until they expire or a higher power user manually redacts them. +Ideally, invites *should not* be exposed by the +[`/_matrix/client/v3/rooms/{roomId}/state`](https://spec.matrix.org/v1.7/client-server-api/#get_matrixclientv3roomsroomidstate) +endpoint *unless* the requesting user has the power level required to list invites. Any invites +created by the requesting user *should* be returned, regardless of the user's power level. It is +assumed that a user with invites has, or had the power level required to create their own invites, + so they should remain accessible to them until they expire or a higher power user manually redacts them. New endpoint: #### **GET** `/_matrix/client/v3/rooms/{roomId}/invites` -Get the invites created for a room. This endpoint should be restricted by a user's power level in a room to prevent leaking invite keys to default or lower power members in a restricted room. +Get the invites created for a room. This endpoint should be restricted by a user's power level in a room to + prevent leaking invite keys to default or lower power members in a restricted room. | Rate-limited | No | | ----------------------- | --- | @@ -136,7 +152,8 @@ Get the invites created for a room. This endpoint should be restricted by a user Array of [`ClientEvent`](https://spec.matrix.org/v1.7/client-server-api/#room-event-format) -If a user has sufficient power to list either their own invites, or that of other users, but none exist, respond with an empty array. +If a user has sufficient power to list either their own invites, or that of other users, but none exist, +respond with an empty array. ###### 403 Response @@ -192,7 +209,8 @@ Add extra content fields to allow a user submit their *state_key* and *secret ke [`POST /_matrix/client/v3/rooms/{roomId}/join`](https://spec.matrix.org/v1.7/client-server-api/#post_matrixclientv3roomsroomidjoin) -Create another optional block for when the user has provided the necessary information to join a room via pre-generated invite code, modeled after the existing *Third-party Signed* block. +Create another optional block for when the user has provided the necessary information +to join a room via pre-generated invite code, modeled after the existing *Third-party Signed* block. | Pre-generated key | | | @@ -255,11 +273,18 @@ can follow. ### Generate and store invites differently -Much of the complexity arises from storing, authenticating and transmitting invites while trying to minimize new additions. Alternatively invites could be removed entirely from the event history and put directly in the database of the resident homeserver, as well as allow powerful room members to request an invite code and generate a url directly from the resident homeserver. +Much of the complexity arises from storing, authenticating and transmitting invites while trying to minimize new + additions. Alternatively invites could be removed entirely from the event history and put directly in the + database of the resident homeserver, as well as allow powerful room members to request an invite code and + generate a url directly from the resident homeserver. -Instead of URIs that look like `!irs2iosct:example.com#MwhqK12Rs4/inviteme!` as proposed by the MSC, this could instead yield much prettier urls such as `https://invite.example.com/invitecode` and cleaner invite codes like `invitecode:example.com` +Instead of URIs that look like `!irs2iosct:example.com#MwhqK12Rs4/inviteme!` as proposed by the MSC, +this could instead yield much prettier urls such as `https://invite.example.com/invitecode` +and cleaner invite codes like `invitecode:example.com` -A stopgap between these two could be an integration or extension of homeserver services that serves as a url shortener such as bit.ly, to avoid needing a deeper rewrite of the spec while maintaining url readability of Matrix's competitor. +A stopgap between these two could be an integration or extension of homeserver services that +serves as a url shortener such as bit.ly, to avoid needing a deeper rewrite of the spec while +maintaining url readability of Matrix's competitor. ## Security considerations @@ -267,13 +292,19 @@ A stopgap between these two could be an integration or extension of homeserver s ### Unintentionally leaking the secret key -The method of authenticating an invite code here would expose the raw *secret key* to a user's homeserver and possibly the redirection service used by a user's client. Specifically this may expose *secret key*s to [https://matrix.to](https://matrix.to) as it is Element's default url redirector. +The method of authenticating an invite code here would expose the raw *secret key* to a user's homeserver +and possibly the redirection service used by a user's client. Specifically this may expose *secret key*s to +[https://matrix.to](https://matrix.to) as it is Element's default url redirector. -Since it is unavoidable to expose the secret key to a user's personal homeserver, it will be assumed a user's homeserver is trusted. +Since it is unavoidable to expose the secret key to a user's personal homeserver, it will be assumed a user's +homeserver is trusted. -In this case, a remedy to this issue would allowing the user's homeserver to define a something along the lines of a `redirection_provider` in the `.well-known/matrix/client` that overrides the client's default redirection service. This way an invitee would have to intentionally attach the invite credentials to an untrusted redirection provider. +In this case, a remedy to this issue would allowing the user's homeserver to define a something along the lines +of a `redirection_provider` in the `.well-known/matrix/client` that overrides the client's default redirection +service. This way an invitee would have to intentionally attach the invite credentials to an untrusted redirection provider. -Alternatively the process of generating valid invite links (not invite codes) could be offloaded to the resident homeserver itself. See alternatives above. +Alternatively the process of generating valid invite links (not invite codes) could be offloaded to the resident +homeserver itself. See alternatives above.