From 566b8af2a4357ae2fb9fca28814dc7d4a36d37aa Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Fri, 18 Jun 2021 12:18:23 +0100 Subject: [PATCH] Initial support for MSC3083 via MSC3244 --- .../tabs/room/SecurityRoomSettingsTab.tsx | 33 +++++++++++++++---- src/createRoom.ts | 28 +++++++++++++--- 2 files changed, 51 insertions(+), 10 deletions(-) diff --git a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx index a9dfd67ca9..2913fb1036 100644 --- a/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx +++ b/src/components/views/settings/tabs/room/SecurityRoomSettingsTab.tsx @@ -42,12 +42,14 @@ interface IState { history: HistoryVisibility; hasAliases: boolean; encrypted: boolean; + roomVersionsCapability?: IRoomVersionsCapability; } enum RoomVisibility { InviteOnly = "invite_only", PublicNoGuests = "public_no_guests", PublicWithGuests = "public_with_guests", + Restricted = "restricted", } @replaceableComponent("views.settings.tabs.room.SecurityRoomSettingsTab") @@ -92,6 +94,9 @@ export default class SecurityRoomSettingsTab extends React.Component this.setState({ hasAliases })); + cli.getCapabilities().then(capabilities => this.setState({ + roomVersionsCapability: capabilities["m.room_versions"], + })); } private pullContentPropertyFromEvent(event: MatrixEvent, key: string, defaultValue: T): T { @@ -166,12 +171,12 @@ export default class SecurityRoomSettingsTab extends React.Component { // join_rule - // INVITE | PUBLIC - // ----------------------+---------------- - // guest CAN_JOIN | inv_only | pub_with_guest - // access ----------------------+---------------- - // FORBIDDEN | inv_only | pub_no_guest - // ----------------------+---------------- + // INVITE | PUBLIC | RESTRICTED + // -----------+----------+----------------+------------- + // guest CAN_JOIN | inv_only | pub_with_guest | restricted + // access -----------+----------+----------------+------------- + // FORBIDDEN | inv_only | pub_no_guest | restricted + // -----------+----------+----------------+------------- // we always set guests can_join here as it makes no sense to have // an invite-only room that guests can't join. If you explicitly @@ -185,6 +190,9 @@ export default class SecurityRoomSettingsTab extends React.Component { guestWarning } diff --git a/src/createRoom.ts b/src/createRoom.ts index 2641492588..0b51613846 100644 --- a/src/createRoom.ts +++ b/src/createRoom.ts @@ -18,6 +18,8 @@ limitations under the License. import { MatrixClient } from "matrix-js-sdk/src/client"; import { Room } from "matrix-js-sdk/src/models/room"; import { EventType } from "matrix-js-sdk/src/@types/event"; +import { ICreateRoomOpts } from "matrix-js-sdk/src/@types/requests"; +import { JoinRule, Preset, Visibility } from "matrix-js-sdk/src/@types/partials"; import { MatrixClientPeg } from './MatrixClientPeg'; import Modal from './Modal'; @@ -35,8 +37,6 @@ import { VIRTUAL_ROOM_EVENT_TYPE } from "./CallHandler"; import SpaceStore from "./stores/SpaceStore"; import { makeSpaceParentEvent } from "./utils/space"; import { Action } from "./dispatcher/actions" -import { ICreateRoomOpts } from "matrix-js-sdk/src/@types/requests"; -import { Preset, Visibility } from "matrix-js-sdk/src/@types/partials"; // we define a number of interfaces which take their names from the js-sdk /* eslint-disable camelcase */ @@ -72,7 +72,7 @@ export interface IOpts { * @returns {Promise} which resolves to the room id, or null if the * action was aborted or failed. */ -export default function createRoom(opts: IOpts): Promise { +export default async function createRoom(opts: IOpts): Promise { opts = opts || {}; if (opts.spinner === undefined) opts.spinner = true; if (opts.guestAccess === undefined) opts.guestAccess = true; @@ -86,7 +86,7 @@ export default function createRoom(opts: IOpts): Promise { const client = MatrixClientPeg.get(); if (client.isGuest()) { dis.dispatch({action: 'require_registration'}); - return Promise.resolve(null); + return null; } const defaultPreset = opts.dmUserId ? Preset.TrustedPrivateChat : Preset.PrivateChat; @@ -150,6 +150,26 @@ export default function createRoom(opts: IOpts): Promise { "history_visibility": opts.createOpts.preset === Preset.PublicChat ? "world_readable" : "invited", }, }); + + if (opts.parentSpace.getJoinRule() !== JoinRule.Public && opts.createOpts.preset !== Preset.PublicChat) { + const serverCapabilities = await client.getCapabilities(); + const roomCapabilities = serverCapabilities?.["m.room_versions"]?.["org.matrix.msc3244.room_capabilities"]; + if (roomCapabilities?.["restricted"]) { + opts.createOpts.room_version = roomCapabilities?.["restricted"].preferred; + + opts.createOpts.initial_state.push({ + type: EventType.RoomJoinRules, + content: { + "join_rule": JoinRule.Restricted, + "allow": [{ + "type": "m.room_membership", + "room_id": opts.parentSpace.roomId, + }], + "authorised_servers": [client.getDomain()], // TODO this might want tweaking + }, + }) + } + } } let modal;