diff --git a/src/components/structures/LoggedInView.js b/src/components/structures/LoggedInView.js
index 5b617feb68..2bc6522232 100644
--- a/src/components/structures/LoggedInView.js
+++ b/src/components/structures/LoggedInView.js
@@ -433,18 +433,22 @@ const LoggedInView = React.createClass({
break;
}
- const mauLimitEvent = this.state.serverNoticeEvents.find((e) => {
- return e && e.getType() === 'm.server_notice.usage_limit_reached' &&
- e.getContent().limit_type &&
- e.getContent().limit_type === 'monthly_active_user'
+ const usageLimitEvent = this.state.serverNoticeEvents.find((e) => {
+ return e && e.getType() === 'm.server_notice.usage_limit_reached';
});
let topBar;
const isGuest = this.props.matrixClient.isGuest();
- if (this.state.syncErrorData && this.state.syncErrorData.error.errcode === 'M_MAU_LIMIT_EXCEEDED') {
- topBar = ;
- } else if (mauLimitEvent) {
- topBar = ;
+ if (this.state.syncErrorData && this.state.syncErrorData.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') {
+ topBar = ;
+ } else if (usageLimitEvent) {
+ topBar = ;
} else if (this.props.showCookieBar &&
this.props.config.piwik
) {
diff --git a/src/components/structures/RoomStatusBar.js b/src/components/structures/RoomStatusBar.js
index ef82ed4bad..fec59aadd5 100644
--- a/src/components/structures/RoomStatusBar.js
+++ b/src/components/structures/RoomStatusBar.js
@@ -18,7 +18,7 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
import Matrix from 'matrix-js-sdk';
-import { _t } from '../../languageHandler';
+import { _t, _td } from '../../languageHandler';
import sdk from '../../index';
import WhoIsTyping from '../../WhoIsTyping';
import MatrixClientPeg from '../../MatrixClientPeg';
@@ -26,6 +26,7 @@ import MemberAvatar from '../views/avatars/MemberAvatar';
import Resend from '../../Resend';
import * as cryptodevices from '../../cryptodevices';
import dis from '../../dispatcher';
+import { messageForResourceLimitError } from '../../utils/ErrorUtils';
const STATUS_BAR_HIDDEN = 0;
const STATUS_BAR_EXPANDED = 1;
@@ -293,11 +294,11 @@ module.exports = React.createClass({
// It also trumps the "some not sent" msg since you can't resend without
// a connection!
// There's one situation in which we don't show this 'no connection' bar, and that's
- // if it's a monthly-active-user limit error: those are shown in the top bar.
+ // if it's a resource limit exceeded error: those are shown in the top bar.
const errorIsMauError = Boolean(
this.state.syncStateData &&
this.state.syncStateData.error &&
- this.state.syncStateData.error.errcode === 'M_MAU_LIMIT_EXCEEDED'
+ this.state.syncStateData.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED'
);
return this.state.syncState === "ERROR" && !errorIsMauError;
},
@@ -326,13 +327,13 @@ module.exports = React.createClass({
);
} else {
let consentError = null;
- let mauError = null;
+ let resourceLimitError = null;
for (const m of unsentMessages) {
if (m.error && m.error.errcode === 'M_CONSENT_NOT_GIVEN') {
consentError = m.error;
break;
- } else if (m.error && m.error.errcode === 'M_MAU_LIMIT_EXCEEDED') {
- mauError = m.error;
+ } else if (m.error && m.error.errcode === 'M_RESOURCE_LIMIT_EXCEEDED') {
+ resourceLimitError = m.error;
break;
}
}
@@ -348,8 +349,19 @@ module.exports = React.createClass({
,
},
);
- } else if (mauError) {
- title = _t("Your message wasn’t sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.");
+ } else if (resourceLimitError) {
+ title = messageForResourceLimitError(
+ resourceLimitError.data.limit_type,
+ resourceLimitError.data.admin_contact, {
+ 'monthly_active_user': _td(
+ "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. " +
+ "Please contact your service administrator to continue using the service.",
+ ),
+ '': _td(
+ "Your message wasn't sent because this homeserver has exceeded a resource limit. " +
+ "Please contact your service administrator to continue using the service.",
+ ),
+ });
} else if (
unsentMessages.length === 1 &&
unsentMessages[0].error &&
diff --git a/src/components/structures/login/Login.js b/src/components/structures/login/Login.js
index cac1c99f24..45f523f141 100644
--- a/src/components/structures/login/Login.js
+++ b/src/components/structures/login/Login.js
@@ -20,11 +20,12 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
-import { _t } from '../../../languageHandler';
+import { _t, _td } from '../../../languageHandler';
import sdk from '../../../index';
import Login from '../../../Login';
import SdkConfig from '../../../SdkConfig';
import SettingsStore from "../../../settings/SettingsStore";
+import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
// For validating phone numbers without country codes
const PHONE_NUMBER_REGEX = /^[0-9()\-\s]*$/;
@@ -121,13 +122,28 @@ module.exports = React.createClass({
const usingEmail = username.indexOf("@") > 0;
if (error.httpStatus === 400 && usingEmail) {
errorText = _t('This Home Server does not support login using email address.');
- } else if (error.errcode == 'M_MAU_LIMIT_EXCEEDED') {
+ } else if (error.errcode == 'M_RESOURCE_LIMIT_EXCEEDED') {
+ const errorTop = messageForResourceLimitError(
+ error.data.limit_type,
+ error.data.admin_contact, {
+ 'monthly_active_user': _td(
+ "This homeserver has hit its Monthly Active User limit.",
+ ),
+ '': _td(
+ "This homeserver has exceeded one of its resource limits.",
+ ),
+ });
+ const errorDetail = messageForResourceLimitError(
+ error.data.limit_type,
+ error.data.admin_contact, {
+ '': _td(
+ "Please contact your service administrator to continue using this service.",
+ ),
+ });
errorText = (
-
{ _t('This homeserver has hit its Monthly Active User limit') }
-
- { _t('Please contact your service administrator to continue using this service.') }
-
+
{errorTop}
+
{errorDetail}
);
} else if (error.httpStatus === 401 || error.httpStatus === 403) {
diff --git a/src/components/structures/login/Registration.js b/src/components/structures/login/Registration.js
index 1f6a2fbcdb..1131218311 100644
--- a/src/components/structures/login/Registration.js
+++ b/src/components/structures/login/Registration.js
@@ -26,9 +26,10 @@ import sdk from '../../../index';
import MatrixClientPeg from '../../../MatrixClientPeg';
import RegistrationForm from '../../views/login/RegistrationForm';
import RtsClient from '../../../RtsClient';
-import { _t } from '../../../languageHandler';
+import { _t, _td } from '../../../languageHandler';
import SdkConfig from '../../../SdkConfig';
import SettingsStore from "../../../settings/SettingsStore";
+import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
const MIN_PASSWORD_LENGTH = 6;
@@ -164,10 +165,27 @@ module.exports = React.createClass({
if (!success) {
let msg = response.message || response.toString();
// can we give a better error message?
- if (response.errcode == 'M_MAU_LIMIT_EXCEEDED') {
+ if (response.errcode == 'M_RESOURCE_LIMIT_EXCEEDED') {
+ const errorTop = messageForResourceLimitError(
+ response.data.limit_type,
+ response.data.admin_contact, {
+ 'monthly_active_user': _td(
+ "This homeserver has hit its Monthly Active User limit.",
+ ),
+ '': _td(
+ "This homeserver has exceeded one of its resource limits.",
+ ),
+ });
+ const errorDetail = messageForResourceLimitError(
+ response.data.limit_type,
+ response.data.admin_contact, {
+ '': _td(
+ "Please contact your service administrator to continue using this service.",
+ ),
+ });
msg =
-
{_t("This homeserver has hit its Monthly Active User limit")}
-
{_t("Please contact your service administrator to continue using this service.")}
+
{errorTop}
+
{errorDetail}
;
} else if (response.required_stages && response.required_stages.indexOf('m.login.msisdn') > -1) {
let msisdnAvailable = false;
diff --git a/src/components/views/globals/ServerLimitBar.js b/src/components/views/globals/ServerLimitBar.js
index c0a7376bd6..0b924fd2e2 100644
--- a/src/components/views/globals/ServerLimitBar.js
+++ b/src/components/views/globals/ServerLimitBar.js
@@ -17,13 +17,16 @@ limitations under the License.
import React from 'react';
import PropTypes from 'prop-types';
import classNames from 'classnames';
-import { _t } from '../../../languageHandler';
+import { _td } from '../../../languageHandler';
+import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
export default React.createClass({
propTypes: {
// 'hard' if the logged in user has been locked out, 'soft' if they haven't
kind: PropTypes.string,
- adminContent: PropTypes.string,
+ adminContact: PropTypes.string,
+ // The type of limit that has been hit.
+ limitType: PropTypes.string.isRequired,
},
getDefaultProps: function() {
@@ -36,42 +39,58 @@ export default React.createClass({
const toolbarClasses = {
'mx_MatrixToolbar': true,
};
- let content;
-
- const translateLink = (sub) => {
- if (this.props.adminContent) {
- return {sub};
- } else {
- return sub;
- }
- };
+ let adminContact;
+ let limitError;
if (this.props.kind === 'hard') {
toolbarClasses['mx_MatrixToolbar_error'] = true;
- content = _t(
- "This homeserver has hit its Monthly Active User limit. " +
- "Please contact your service administrator to continue using the service.",
- {},
+
+ adminContact = messageForResourceLimitError(
+ this.props.limitType,
+ this.props.adminContact,
{
- 'a': translateLink,
+ '': _td("Please contact your service administrator to continue using the service."),
+ },
+ );
+ limitError = messageForResourceLimitError(
+ this.props.limitType,
+ this.props.adminContact,
+ {
+ 'monthly_active_user': _td("This homeserver has hit its Monthly Active User limit."),
+ '': _td("This homeserver has exceeded one of its resource limits."),
},
);
} else {
toolbarClasses['mx_MatrixToolbar_info'] = true;
- content = _t(
- "This homeserver has hit its Monthly Active User " +
- "limit so some users will not be able to log in. " +
- "Please contact your service administrator to get this limit increased.",
- {},
+ adminContact = messageForResourceLimitError(
+ this.props.limitType,
+ this.props.adminContact,
{
- 'a': translateLink,
+ '': _td("Please contact your service administrator to get this limit increased."),
},
);
+ limitError = messageForResourceLimitError(
+ this.props.limitType,
+ this.props.adminContact,
+ {
+ 'monthly_active_user': _td(
+ "This homeserver has hit its Monthly Active User limit so " +
+ "some users will not be able to log in.",
+ ),
+ '': _td(
+ "This homeserver has exceeded one of its resource limits so " +
+ "some users will not be able to log in.",
+ ),
+ },
+ {'b': sub => {sub}},
+ );
}
return (
- { content }
+ {limitError}
+ {' '}
+ {adminContact}
);
diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json
index 08c7ae086d..1afa35d8fd 100644
--- a/src/i18n/strings/en_EN.json
+++ b/src/i18n/strings/en_EN.json
@@ -543,6 +543,10 @@
"Internal room ID: ": "Internal room ID: ",
"Room version number: ": "Room version number: ",
"Add a topic": "Add a topic",
+ "There is a known vulnerability affecting this room.": "There is a known vulnerability affecting this room.",
+ "This room version is vulnerable to malicious modification of room state.": "This room version is vulnerable to malicious modification of room state.",
+ "Click here to upgrade to the latest room version and ensure room integrity is protected.": "Click here to upgrade to the latest room version and ensure room integrity is protected.",
+ "Only room administrators will see this warning": "Only room administrators will see this warning",
"Search…": "Search…",
"This Room": "This Room",
"All Rooms": "All Rooms",
@@ -679,8 +683,12 @@
"A new version of Riot is available.": "A new version of Riot is available.",
"To return to your account in future you need to set a password": "To return to your account in future you need to set a password",
"Set Password": "Set Password",
- "This homeserver has hit its Monthly Active User limit. Please contact your service administrator to continue using the service.": "This homeserver has hit its Monthly Active User limit. Please contact your service administrator to continue using the service.",
- "This homeserver has hit its Monthly Active User limit so some users will not be able to log in. Please contact your service administrator to get this limit increased.": "This homeserver has hit its Monthly Active User limit so some users will not be able to log in. Please contact your service administrator to get this limit increased.",
+ "Please contact your service administrator to continue using the service.": "Please contact your service administrator to continue using the service.",
+ "This homeserver has hit its Monthly Active User limit.": "This homeserver has hit its Monthly Active User limit.",
+ "This homeserver has exceeded one of its resource limits.": "This homeserver has exceeded one of its resource limits.",
+ "Please contact your service administrator to get this limit increased.": "Please contact your service administrator to get this limit increased.",
+ "This homeserver has hit its Monthly Active User limit so some users will not be able to log in.": "This homeserver has hit its Monthly Active User limit so some users will not be able to log in.",
+ "This homeserver has exceeded one of its resource limits so some users will not be able to log in.": "This homeserver has exceeded one of its resource limits so some users will not be able to log in.",
"Error encountered (%(errorDetail)s).": "Error encountered (%(errorDetail)s).",
"Checking for an update...": "Checking for an update...",
"No update available.": "No update available.",
@@ -857,6 +865,12 @@
"Ignore request": "Ignore request",
"Loading device info...": "Loading device info...",
"Encryption key request": "Encryption key request",
+ "Upgrade Room Version": "Upgrade Room Version",
+ "Upgrading this room requires closing down the current instance of the room and creating a new room it its place. To give room members the best possible experience, we will:": "Upgrading this room requires closing down the current instance of the room and creating a new room it its place. To give room members the best possible experience, we will:",
+ "Create a new room with the same name, description and avatar": "Create a new room with the same name, description and avatar",
+ "Update any local room aliases to point to the new room": "Update any local room aliases to point to the new room",
+ "Stop users from speaking in the old version of the room, and post a message advising users to move to the new room": "Stop users from speaking in the old version of the room, and post a message advising users to move to the new room",
+ "Put a link back to the old room at the start of the new room so people can see old messages": "Put a link back to the old room at the start of the new room so people can see old messages",
"Sign out": "Sign out",
"Log out and remove encryption keys?": "Log out and remove encryption keys?",
"Clear Storage and Sign Out": "Clear Storage and Sign Out",
@@ -1039,7 +1053,8 @@
"Message not sent due to unknown devices being present": "Message not sent due to unknown devices being present",
"Show devices, send anyway or cancel.": "Show devices, send anyway or cancel.",
"You can't send any messages until you review and agree to our terms and conditions.": "You can't send any messages until you review and agree to our terms and conditions.",
- "Your message wasn’t sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Your message wasn’t sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.",
+ "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.": "Your message wasn't sent because this homeserver has hit its Monthly Active User Limit. Please contact your service administrator to continue using the service.",
+ "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.": "Your message wasn't sent because this homeserver has exceeded a resource limit. Please contact your service administrator to continue using the service.",
"%(count)s of your messages have not been sent.|other": "Some of your messages have not been sent.",
"%(count)s of your messages have not been sent.|one": "Your message was not sent.",
"%(count)s Resend all or cancel all now. You can also select individual messages to resend or cancel.|other": "Resend all or cancel all now. You can also select individual messages to resend or cancel.",
@@ -1156,8 +1171,7 @@
"Send Reset Email": "Send Reset Email",
"Create an account": "Create an account",
"This Home Server does not support login using email address.": "This Home Server does not support login using email address.",
- "This homeserver has hit its Monthly Active User limit": "This homeserver has hit its Monthly Active User limit",
- "Please contact your service administrator to continue using this service.": "Please contact your service administrator to continue using this service.",
+ "Please contact your service administrator to continue using this service.": "Please contact your service administrator to continue using this service.",
"Incorrect username and/or password.": "Incorrect username and/or password.",
"Please note you are logging into the %(hs)s server, not matrix.org.": "Please note you are logging into the %(hs)s server, not matrix.org.",
"Guest access is disabled on this Home Server.": "Guest access is disabled on this Home Server.",
diff --git a/src/utils/ErrorUtils.js b/src/utils/ErrorUtils.js
new file mode 100644
index 0000000000..97a29a3572
--- /dev/null
+++ b/src/utils/ErrorUtils.js
@@ -0,0 +1,50 @@
+/*
+Copyright 2018 New Vector 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.
+*/
+
+import { _t } from '../languageHandler';
+
+/**
+ * Produce a translated error message for a
+ * M_RESOURCE_LIMIT_EXCEEDED error
+ *
+ * @param {string} limitType The limit_type from the error
+ * @param {string} adminContact The admin_contact from the error
+ * @param {Object} strings Translateable string for different
+ * limit_type. Must include at least the empty string key
+ * which is the default. Strings may include an 'a' tag
+ * for the admin contact link.
+ * @param {Object} extraTranslations Extra translation substitution functions
+ * for any tags in the strings apart from 'a'
+ * @returns {*} Translated string or react component
+ */
+export function messageForResourceLimitError(limitType, adminContact, strings, extraTranslations) {
+ let errString = strings[limitType];
+ if (errString === undefined) errString = strings[''];
+
+ const linkSub = sub => {
+ if (adminContact) {
+ return {sub};
+ } else {
+ return sub;
+ }
+ };
+
+ if (errString.includes('')) {
+ return _t(errString, {}, Object.assign({ 'a': linkSub }, extraTranslations));
+ } else {
+ return _t(errString, {}, extraTranslations);
+ }
+}