Initial support for MSC3083 via MSC3244
parent
e508ff003b
commit
566b8af2a4
|
@ -42,12 +42,14 @@ interface IState {
|
||||||
history: HistoryVisibility;
|
history: HistoryVisibility;
|
||||||
hasAliases: boolean;
|
hasAliases: boolean;
|
||||||
encrypted: boolean;
|
encrypted: boolean;
|
||||||
|
roomVersionsCapability?: IRoomVersionsCapability;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum RoomVisibility {
|
enum RoomVisibility {
|
||||||
InviteOnly = "invite_only",
|
InviteOnly = "invite_only",
|
||||||
PublicNoGuests = "public_no_guests",
|
PublicNoGuests = "public_no_guests",
|
||||||
PublicWithGuests = "public_with_guests",
|
PublicWithGuests = "public_with_guests",
|
||||||
|
Restricted = "restricted",
|
||||||
}
|
}
|
||||||
|
|
||||||
@replaceableComponent("views.settings.tabs.room.SecurityRoomSettingsTab")
|
@replaceableComponent("views.settings.tabs.room.SecurityRoomSettingsTab")
|
||||||
|
@ -92,6 +94,9 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
this.setState({ joinRule, guestAccess, history, encrypted });
|
this.setState({ joinRule, guestAccess, history, encrypted });
|
||||||
|
|
||||||
this.hasAliases().then(hasAliases => this.setState({ hasAliases }));
|
this.hasAliases().then(hasAliases => this.setState({ hasAliases }));
|
||||||
|
cli.getCapabilities().then(capabilities => this.setState({
|
||||||
|
roomVersionsCapability: capabilities["m.room_versions"],
|
||||||
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
private pullContentPropertyFromEvent<T>(event: MatrixEvent, key: string, defaultValue: T): T {
|
private pullContentPropertyFromEvent<T>(event: MatrixEvent, key: string, defaultValue: T): T {
|
||||||
|
@ -166,12 +171,12 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
|
|
||||||
private onRoomAccessRadioToggle = (roomAccess: RoomVisibility) => {
|
private onRoomAccessRadioToggle = (roomAccess: RoomVisibility) => {
|
||||||
// join_rule
|
// join_rule
|
||||||
// INVITE | PUBLIC
|
// INVITE | PUBLIC | RESTRICTED
|
||||||
// ----------------------+----------------
|
// -----------+----------+----------------+-------------
|
||||||
// guest CAN_JOIN | inv_only | pub_with_guest
|
// guest CAN_JOIN | inv_only | pub_with_guest | restricted
|
||||||
// access ----------------------+----------------
|
// access -----------+----------+----------------+-------------
|
||||||
// FORBIDDEN | inv_only | pub_no_guest
|
// FORBIDDEN | inv_only | pub_no_guest | restricted
|
||||||
// ----------------------+----------------
|
// -----------+----------+----------------+-------------
|
||||||
|
|
||||||
// we always set guests can_join here as it makes no sense to have
|
// 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
|
// an invite-only room that guests can't join. If you explicitly
|
||||||
|
@ -185,6 +190,9 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
case RoomVisibility.InviteOnly:
|
case RoomVisibility.InviteOnly:
|
||||||
// no change - use defaults above
|
// no change - use defaults above
|
||||||
break;
|
break;
|
||||||
|
case RoomVisibility.Restricted:
|
||||||
|
joinRule = JoinRule.Restricted;
|
||||||
|
break;
|
||||||
case RoomVisibility.PublicNoGuests:
|
case RoomVisibility.PublicNoGuests:
|
||||||
joinRule = JoinRule.Public;
|
joinRule = JoinRule.Public;
|
||||||
guestAccess = GuestAccess.Forbidden;
|
guestAccess = GuestAccess.Forbidden;
|
||||||
|
@ -295,6 +303,19 @@ export default class SecurityRoomSettingsTab extends React.Component<IProps, ISt
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const roomCapabilities = this.state.roomVersionsCapability?.["org.matrix.msc3244.room_capabilities"];
|
||||||
|
if (roomCapabilities?.["restricted"]) {
|
||||||
|
if (Array.isArray(roomCapabilities["restricted"]?.support) &&
|
||||||
|
roomCapabilities["restricted"].support.includes(room.getVersion() ?? "1")
|
||||||
|
) {
|
||||||
|
radioDefinitions.unshift({
|
||||||
|
value: RoomVisibility.Restricted,
|
||||||
|
label: _t("Only people in certain spaces or those who have been invited (TODO copy)"),
|
||||||
|
checked: joinRule === JoinRule.Restricted,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{ guestWarning }
|
{ guestWarning }
|
||||||
|
|
|
@ -18,6 +18,8 @@ limitations under the License.
|
||||||
import { MatrixClient } from "matrix-js-sdk/src/client";
|
import { MatrixClient } from "matrix-js-sdk/src/client";
|
||||||
import { Room } from "matrix-js-sdk/src/models/room";
|
import { Room } from "matrix-js-sdk/src/models/room";
|
||||||
import { EventType } from "matrix-js-sdk/src/@types/event";
|
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 { MatrixClientPeg } from './MatrixClientPeg';
|
||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
|
@ -35,8 +37,6 @@ import { VIRTUAL_ROOM_EVENT_TYPE } from "./CallHandler";
|
||||||
import SpaceStore from "./stores/SpaceStore";
|
import SpaceStore from "./stores/SpaceStore";
|
||||||
import { makeSpaceParentEvent } from "./utils/space";
|
import { makeSpaceParentEvent } from "./utils/space";
|
||||||
import { Action } from "./dispatcher/actions"
|
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
|
// we define a number of interfaces which take their names from the js-sdk
|
||||||
/* eslint-disable camelcase */
|
/* eslint-disable camelcase */
|
||||||
|
@ -72,7 +72,7 @@ export interface IOpts {
|
||||||
* @returns {Promise} which resolves to the room id, or null if the
|
* @returns {Promise} which resolves to the room id, or null if the
|
||||||
* action was aborted or failed.
|
* action was aborted or failed.
|
||||||
*/
|
*/
|
||||||
export default function createRoom(opts: IOpts): Promise<string | null> {
|
export default async function createRoom(opts: IOpts): Promise<string | null> {
|
||||||
opts = opts || {};
|
opts = opts || {};
|
||||||
if (opts.spinner === undefined) opts.spinner = true;
|
if (opts.spinner === undefined) opts.spinner = true;
|
||||||
if (opts.guestAccess === undefined) opts.guestAccess = true;
|
if (opts.guestAccess === undefined) opts.guestAccess = true;
|
||||||
|
@ -86,7 +86,7 @@ export default function createRoom(opts: IOpts): Promise<string | null> {
|
||||||
const client = MatrixClientPeg.get();
|
const client = MatrixClientPeg.get();
|
||||||
if (client.isGuest()) {
|
if (client.isGuest()) {
|
||||||
dis.dispatch({action: 'require_registration'});
|
dis.dispatch({action: 'require_registration'});
|
||||||
return Promise.resolve(null);
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultPreset = opts.dmUserId ? Preset.TrustedPrivateChat : Preset.PrivateChat;
|
const defaultPreset = opts.dmUserId ? Preset.TrustedPrivateChat : Preset.PrivateChat;
|
||||||
|
@ -150,6 +150,26 @@ export default function createRoom(opts: IOpts): Promise<string | null> {
|
||||||
"history_visibility": opts.createOpts.preset === Preset.PublicChat ? "world_readable" : "invited",
|
"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;
|
let modal;
|
||||||
|
|
Loading…
Reference in New Issue