From c1c32e32689519ac0655b89f28832a51351fd5dd Mon Sep 17 00:00:00 2001 From: Timo Paulssen Date: Fri, 17 Apr 2020 00:09:56 +0200 Subject: [PATCH] Offer "alias" field in room create form Tries its best to not allow aliases that are too long (full alias including leading #, : in the middle, and homeserver domain name must not exceed 255 bytes. Change-Id: I1e784a94cb599eca7e30736d666b20e37aad5444 --- src/components/rooms.js | 57 +++++++++++++++++++++++++++++++++++-- src/i18n/de.js | 6 ++++ src/i18n/en.js | 6 ++++ src/synapse/dataProvider.js | 2 ++ 4 files changed, 69 insertions(+), 2 deletions(-) diff --git a/src/components/rooms.js b/src/components/rooms.js index f8612b6..57c113e 100644 --- a/src/components/rooms.js +++ b/src/components/rooms.js @@ -29,20 +29,73 @@ function generateRoomRecord() { return { room_name: "", public: true, + alias: "", } } const validateDisplayName = fieldval => fieldval === undefined ? "synapseadmin.rooms.room_name_required" : fieldval.length === 0 ? "synapseadmin.rooms.room_name_required" : undefined; +function approximateAliasLength(alias, homeserver) { + /* TODO maybe handle punycode in homeserver URL */ + + var te; + + // Support for TextEncoder is quite widespread, but the polyfill is + // pretty large; We will only underestimate the size with the regular + // length attribute of String, so we never prevent the user from using + // an alias that is short enough for the server, but too long for our + // heuristic. + try { + te = new TextEncoder(); + } + catch (err) { + if (err instanceof ReferenceError) { + te = undefined; + } + } + + const aliasLength = te === undefined ? alias.length : te.encode(alias).length; + + return ( + "#".length + + aliasLength + + ":".length + + homeserver.length + ); +} + +const validateAlias = fieldval => { + if (fieldval === undefined) { + return undefined; + } + const homeserver = localStorage.getItem("home_server"); + + if (approximateAliasLength(fieldval, homeserver) > 255) { + return "synapseadmin.rooms.alias_too_long"; + } +} + const removeLeadingWhitespace = fieldVal => fieldVal === undefined ? undefined : fieldVal.trimStart(); +const validateHasAliasIfPublic = formdata => { + let errors = {}; + if (formdata.public) { + if (formdata.alias === undefined || formdata.alias.trim().length === 0) { + errors.alias = "synapseadmin.rooms.alias_required_if_public" + } + } + return errors; +} + export const RoomCreate = props => ( - + + diff --git a/src/i18n/de.js b/src/i18n/de.js index 4e4b67c..452584b 100644 --- a/src/i18n/de.js +++ b/src/i18n/de.js @@ -21,6 +21,12 @@ export default { make_public: "Öffentlicher Raum", room_name_required: "Muss angegeben werden", + alias_required_if_public: + "Muss für öffentliche Räume angegeben werden.", + alias: + "Alias", + alias_too_long: + "Darf zusammen mit der Domain des Homeservers 255 bytes nicht überschreiten" } }, resources: { diff --git a/src/i18n/en.js b/src/i18n/en.js index d8cb0a4..f6382d9 100644 --- a/src/i18n/en.js +++ b/src/i18n/en.js @@ -21,6 +21,12 @@ export default { make_public: "Make room public", room_name_required: "Must be provided", + alias_required_if_public: + "Must be provided for a public room", + alias: + "Alias", + alias_too_long: + "Must not exceed 255 bytes including the domain of the homeserver." } }, resources: { diff --git a/src/synapse/dataProvider.js b/src/synapse/dataProvider.js index d47576d..0f24749 100644 --- a/src/synapse/dataProvider.js +++ b/src/synapse/dataProvider.js @@ -83,8 +83,10 @@ const roomCreationProvider = { const newParams = { ...params.data, public: undefined, room_name: undefined, + alias: undefined, name: params.data.room_name, + room_alias_name: params.data.alias, visibility: params.data.public ? "public" : "private", }