From 5f1fabd982c3749d9cc9e83de3efeff032d34ed2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 10:57:05 +0000 Subject: [PATCH 01/11] Error message #1: guests can't invite people. Also add a dialog box for telling people they need to register. --- src/component-index.js | 1 + .../views/dialogs/NeedToRegisterDialog.js | 76 +++++++++++++++++++ src/components/views/rooms/MemberList.js | 9 +++ 3 files changed, 86 insertions(+) create mode 100644 src/components/views/dialogs/NeedToRegisterDialog.js diff --git a/src/component-index.js b/src/component-index.js index 869d60f204..67c09e61a6 100644 --- a/src/component-index.js +++ b/src/component-index.js @@ -46,6 +46,7 @@ module.exports.components['views.create_room.Presets'] = require('./components/v module.exports.components['views.create_room.RoomAlias'] = require('./components/views/create_room/RoomAlias'); module.exports.components['views.dialogs.ErrorDialog'] = require('./components/views/dialogs/ErrorDialog'); module.exports.components['views.dialogs.LogoutPrompt'] = require('./components/views/dialogs/LogoutPrompt'); +module.exports.components['views.dialogs.NeedToRegisterDialog'] = require('./components/views/dialogs/NeedToRegisterDialog'); module.exports.components['views.dialogs.QuestionDialog'] = require('./components/views/dialogs/QuestionDialog'); module.exports.components['views.dialogs.SetDisplayNameDialog'] = require('./components/views/dialogs/SetDisplayNameDialog'); module.exports.components['views.dialogs.TextInputDialog'] = require('./components/views/dialogs/TextInputDialog'); diff --git a/src/components/views/dialogs/NeedToRegisterDialog.js b/src/components/views/dialogs/NeedToRegisterDialog.js new file mode 100644 index 0000000000..2ad246503f --- /dev/null +++ b/src/components/views/dialogs/NeedToRegisterDialog.js @@ -0,0 +1,76 @@ +/* +Copyright 2016 OpenMarket Ltd + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* + * Usage: + * Modal.createDialog(NeedToRegisterDialog, { + * title: "some text", (default: "Registration required") + * description: "some more text", + * onClose: someFunction, + * }); + */ + +var React = require("react"); +var dis = require("../../../dispatcher"); + +module.exports = React.createClass({ + displayName: 'NeedToRegisterDialog', + propTypes: { + title: React.PropTypes.string, + description: React.PropTypes.oneOfType([ + React.PropTypes.element, + React.PropTypes.string, + ]), + onFinished: React.PropTypes.func.isRequired, + }, + + getDefaultProps: function() { + return { + title: "Registration required", + description: "A registered account is required for this action", + }; + }, + + onRegisterClicked: function() { + dis.dispatch({ + action: "start_upgrade_registration", + }); + if (this.props.onFinished) { + this.props.onFinished(); + } + }, + + render: function() { + return ( +
+
+ {this.props.title} +
+
+ {this.props.description} +
+
+ + +
+
+ ); + } +}); diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index b15e5bdc94..76f3fd5624 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -142,9 +142,18 @@ module.exports = React.createClass({ onInvite: function(inputText) { var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); var self = this; inputText = inputText.trim(); // react requires es5-shim so we know trim() exists + if (MatrixClientPeg.get().isGuest()) { + Modal.createDialog(NeedToRegisterDialog, { + title: "Unable to Invite", + description: "Guest user can't invite new users. Please register to be able to invite new users into a room." + }); + return; + } + // email addresses and user IDs do not allow space, comma, semicolon so split // on them for bulk inviting. var separators =[ ";", " ", "," ]; From 30b76d372cc26289f5895bf0c7242ffc9400b7d4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 12:58:12 +0000 Subject: [PATCH 02/11] Error messages for guests creating rooms --- src/components/structures/MatrixChat.js | 9 +++++++++ src/components/views/rooms/MemberInfo.js | 10 ++++++++++ 2 files changed, 19 insertions(+) diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js index c16b80ec62..459847ce88 100644 --- a/src/components/structures/MatrixChat.js +++ b/src/components/structures/MatrixChat.js @@ -464,9 +464,18 @@ module.exports = React.createClass({ //this.notifyNewScreen('new'); var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); var Loader = sdk.getComponent("elements.Spinner"); var modal = Modal.createDialog(Loader); + if (MatrixClientPeg.get().isGuest) { + Modal.createDialog(NeedToRegisterDialog, { + title: "Please Register", + description: "Guest users can't create new rooms. Please register to create room and start a chat." + }); + return; + } + // XXX: FIXME: deduplicate this with MemberInfo's 'start chat' impl MatrixClientPeg.get().createRoom({ preset: "private_chat", diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index 196e3e4c5f..a79d90adbc 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -293,6 +293,16 @@ module.exports = React.createClass({ } else { self.setState({ creatingRoom: true }); + + if (MatrixClientPeg.get().isGuest()) { + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + Modal.createDialog(NeedToRegisterDialog, { + title: "Please Register", + description: "Guest users can't create new rooms. Please register to create room and start a chat." + }); + return; + } + MatrixClientPeg.get().createRoom({ // XXX: FIXME: deduplicate this with "view_create_room" in MatrixChat invite: [this.props.member.userId], From 6dce55586557da4801870ae3a2c09add0a923bc0 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 13:09:19 +0000 Subject: [PATCH 03/11] Sensible error for setting room colours if you're a guest --- .../views/room_settings/ColorSettings.js | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/components/views/room_settings/ColorSettings.js b/src/components/views/room_settings/ColorSettings.js index bf931b6c05..ad0b1fe070 100644 --- a/src/components/views/room_settings/ColorSettings.js +++ b/src/components/views/room_settings/ColorSettings.js @@ -16,8 +16,10 @@ limitations under the License. var q = require("q"); var React = require('react'); +var sdk = require('../../../index'); var Tinter = require('../../../Tinter'); var MatrixClientPeg = require("../../../MatrixClientPeg"); +var Modal = require("../../../Modal"); var ROOM_COLORS = [ // magic room default values courtesy of Ribot @@ -74,12 +76,23 @@ module.exports = React.createClass({ if (originalState.primary_color !== this.state.primary_color || originalState.secondary_color !== this.state.secondary_color) { console.log("ColorSettings: Saving new color"); + // We would like guests to be able to set room colour but currently + // they can't, so we still send the request but display a sensible + // error if it fails. return MatrixClientPeg.get().setRoomAccountData( this.props.room.roomId, "org.matrix.room.color_scheme", { primary_color: this.state.primary_color, secondary_color: this.state.secondary_color } - ); + ).catch(function(err) { + if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') { + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + Modal.createDialog(NeedToRegisterDialog, { + title: "Please Register", + description: "Guest users can't create new rooms. Please register to create room and start a chat." + }); + } + }); } return q(); // no color diff }, From 463212fb2a28347f1a0ebb73e7299f79d0c43c7b Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 13:19:29 +0000 Subject: [PATCH 04/11] Update error message --- .../views/room_settings/ColorSettings.js | 2 +- src/components/views/rooms/MemberInfo.js | 16 ++++++++++++---- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/src/components/views/room_settings/ColorSettings.js b/src/components/views/room_settings/ColorSettings.js index ad0b1fe070..fff97ea817 100644 --- a/src/components/views/room_settings/ColorSettings.js +++ b/src/components/views/room_settings/ColorSettings.js @@ -89,7 +89,7 @@ module.exports = React.createClass({ var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); Modal.createDialog(NeedToRegisterDialog, { title: "Please Register", - description: "Guest users can't create new rooms. Please register to create room and start a chat." + description: "Saving room color settings is only available to registered users" }); } }); diff --git a/src/components/views/rooms/MemberInfo.js b/src/components/views/rooms/MemberInfo.js index a79d90adbc..feb4a30bde 100644 --- a/src/components/views/rooms/MemberInfo.js +++ b/src/components/views/rooms/MemberInfo.js @@ -170,10 +170,18 @@ module.exports = React.createClass({ // get out of sync if we force setState here! console.log("Mod toggle success"); }, function(err) { - Modal.createDialog(ErrorDialog, { - title: "Mod error", - description: err.message - }); + if (err.errcode == 'M_GUEST_ACCESS_FORBIDDEN') { + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + Modal.createDialog(NeedToRegisterDialog, { + title: "Please Register", + description: "This action cannot be performed by a guest user. Please register to be able to do this." + }); + } else { + Modal.createDialog(ErrorDialog, { + title: "Mod error", + description: err.message + }); + } } ); this.props.onFinished(); From 13f31b2a5ddc1b46b39caaf694477034e281f5a2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 13:47:29 +0000 Subject: [PATCH 05/11] Add error message for failing to join a room as a guest (which may or may not be because we're a guest: we can't tell) --- src/components/structures/RoomView.js | 28 +++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/components/structures/RoomView.js b/src/components/structures/RoomView.js index 4598b7b9c8..7f4d8ea91a 100644 --- a/src/components/structures/RoomView.js +++ b/src/components/structures/RoomView.js @@ -575,12 +575,28 @@ module.exports = React.createClass({ }); if (!error) return; - var msg = error.message ? error.message : JSON.stringify(error); - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { - title: "Failed to join room", - description: msg - }); + + // https://matrix.org/jira/browse/SYN-659 + if ( + error.errcode == 'M_GUEST_ACCESS_FORBIDDEN' || + ( + error.errcode == 'M_FORBIDDEN' && + MatrixClientPeg.get().isGuest() + ) + ) { + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + Modal.createDialog(NeedToRegisterDialog, { + title: "Failed to join the room", + description: "This room is private or inaccessible to guests. You may be able to join if you register." + }); + } else { + var msg = error.message ? error.message : JSON.stringify(error); + var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); + Modal.createDialog(ErrorDialog, { + title: "Failed to join room", + description: msg + }); + } }); this.setState({ joining: true From f1219a6b8def979ac9c79c21a8c11ce85a38a8c2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 13:50:27 +0000 Subject: [PATCH 06/11] Register prompt for trying to set an avatar --- src/components/structures/UserSettings.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/components/structures/UserSettings.js b/src/components/structures/UserSettings.js index 99198ac691..2ba9caa4e3 100644 --- a/src/components/structures/UserSettings.js +++ b/src/components/structures/UserSettings.js @@ -91,9 +91,9 @@ module.exports = React.createClass({ onAvatarPickerClick: function(ev) { if (MatrixClientPeg.get().isGuest()) { - var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog"); - Modal.createDialog(ErrorDialog, { - title: "Error", + var NeedToRegisterDialog = sdk.getComponent("dialogs.NeedToRegisterDialog"); + Modal.createDialog(NeedToRegisterDialog, { + title: "Please Register", description: "Guests can't set avatars. Please register.", }); return; From 7caad2a434fae9dfbce901095d4d86a6ba485640 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 14:22:16 +0000 Subject: [PATCH 07/11] More user-facing error message for event-not-found --- src/components/structures/TimelinePanel.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 7cb8a22e7c..8ebe764ecf 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -588,8 +588,8 @@ var TimelinePanel = React.createClass({ }; } Modal.createDialog(ErrorDialog, { - title: "Failed to load event", - description: msg, + title: "Failed to load timeline position", + description: "Vector was trying to load a specific point in this room's timeline but was unable to find it.", onFinished: onFinished, }); } From 88aa975271c8896dfd84b0baf4b3f8eca078a912 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 16:33:39 +0000 Subject: [PATCH 08/11] Sensible error message if we can't invite because we're not allowed --- src/components/views/rooms/MemberList.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/views/rooms/MemberList.js b/src/components/views/rooms/MemberList.js index 76f3fd5624..102e33dbd4 100644 --- a/src/components/views/rooms/MemberList.js +++ b/src/components/views/rooms/MemberList.js @@ -231,10 +231,17 @@ module.exports = React.createClass({ }, function(err) { if (err !== null) { console.error("Failed to invite: %s", JSON.stringify(err)); - Modal.createDialog(ErrorDialog, { - title: "Server error whilst inviting", - description: err.message - }); + if (err.errcode == 'M_FORBIDDEN') { + Modal.createDialog(ErrorDialog, { + title: "Unable to Invite", + description: "You do not have permission to invite people to this room." + }); + } else { + Modal.createDialog(ErrorDialog, { + title: "Server error whilst inviting", + description: err.message + }); + } } }).finally(function() { self.setState({ From 7f6eabe65748e0f681d7c80f155927b6462fac10 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 17:20:22 +0000 Subject: [PATCH 09/11] Fix doc for NeedToRegisterDialog and the place I copied it from --- src/components/views/dialogs/ErrorDialog.js | 2 +- src/components/views/dialogs/NeedToRegisterDialog.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/views/dialogs/ErrorDialog.js b/src/components/views/dialogs/ErrorDialog.js index c3f4ca6a55..b3278dfcfe 100644 --- a/src/components/views/dialogs/ErrorDialog.js +++ b/src/components/views/dialogs/ErrorDialog.js @@ -20,7 +20,7 @@ limitations under the License. * title: "some text", (default: "Error") * description: "some more text", * button: "Button Text", - * onClose: someFunction, + * onFinished: someFunction, * focus: true|false (default: true) * }); */ diff --git a/src/components/views/dialogs/NeedToRegisterDialog.js b/src/components/views/dialogs/NeedToRegisterDialog.js index 2ad246503f..1d5b6c3e5e 100644 --- a/src/components/views/dialogs/NeedToRegisterDialog.js +++ b/src/components/views/dialogs/NeedToRegisterDialog.js @@ -19,7 +19,7 @@ limitations under the License. * Modal.createDialog(NeedToRegisterDialog, { * title: "some text", (default: "Registration required") * description: "some more text", - * onClose: someFunction, + * onFinished: someFunction, * }); */ From 4e9c37c0692712fabc6f0738f3a2b213a6f8124a Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 17:23:46 +0000 Subject: [PATCH 10/11] Remove unused prop --- src/components/views/dialogs/NeedToRegisterDialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/views/dialogs/NeedToRegisterDialog.js b/src/components/views/dialogs/NeedToRegisterDialog.js index 1d5b6c3e5e..a6b548881e 100644 --- a/src/components/views/dialogs/NeedToRegisterDialog.js +++ b/src/components/views/dialogs/NeedToRegisterDialog.js @@ -66,7 +66,7 @@ module.exports = React.createClass({ - From 87d853d56b00abf8de433bef8053924e748d05bc Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 22 Mar 2016 17:33:46 +0000 Subject: [PATCH 11/11] If we don't get a specific event because of permissions, say so --- src/components/structures/TimelinePanel.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index 8ebe764ecf..8c2e14a361 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -587,9 +587,15 @@ var TimelinePanel = React.createClass({ }); }; } + var message = "Vector was trying to load a specific point in this room's timeline but "; + if (error.errcode == 'M_FORBIDDEN') { + message += "you do not have permission to view the message in question."; + } else { + message += "was unable to find it."; + } Modal.createDialog(ErrorDialog, { title: "Failed to load timeline position", - description: "Vector was trying to load a specific point in this room's timeline but was unable to find it.", + description: message, onFinished: onFinished, }); }