From 366f7e277a289899288b6b0317b4f6fe97d89ea2 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Aug 2019 11:15:56 +0100 Subject: [PATCH 1/5] Make registration work without an IS. --- src/components/views/auth/RegistrationForm.js | 51 +++++++++++++++---- src/components/views/auth/ServerConfig.js | 2 +- src/i18n/strings/en_EN.json | 2 + src/utils/AutoDiscoveryUtils.js | 18 ++++--- 4 files changed, 57 insertions(+), 16 deletions(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index ad663bee47f..cd3dab12ac9 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -91,14 +91,25 @@ module.exports = React.createClass({ const self = this; if (this.state.email == '') { + const haveIs = Boolean(this.props.serverConfig.isUrl); + + let desc; + if (haveIs) { + desc = _t( + "If you don't specify an email address, you won't be able to reset your password. " + + "Are you sure?", + ); + } else { + desc = _t( + "No Identity Server is configured so you cannot add add an email address in order to " + + "reset your password in the future.", + ); + } + const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog"); Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, { title: _t("Warning!"), - description: -
- { _t("If you don't specify an email address, you won't be able to reset your password. " + - "Are you sure?") } -
, + description: desc, button: _t("Continue"), onFinished: function(confirmed) { if (confirmed) { @@ -423,8 +434,16 @@ module.exports = React.createClass({ }); }, + _showEmail() { + const haveIs = Boolean(this.props.serverConfig.isUrl); + if (!haveIs || !this._authStepIsUsed('m.login.email.identity')) { + return false; + } + return true; + }, + renderEmail() { - if (!this._authStepIsUsed('m.login.email.identity')) { + if (!this._showEmail()) { return null; } const Field = sdk.getComponent('elements.Field'); @@ -473,7 +492,8 @@ module.exports = React.createClass({ renderPhoneNumber() { const threePidLogin = !SdkConfig.get().disable_3pid_login; - if (!threePidLogin || !this._authStepIsUsed('m.login.msisdn')) { + const haveIs = Boolean(this.props.serverConfig.isUrl); + if (!threePidLogin || !haveIs || !this._authStepIsUsed('m.login.msisdn')) { return null; } const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown'); @@ -547,6 +567,19 @@ module.exports = React.createClass({ ); + const emailHelperText = this._showEmail() ?
+ {_t("Use an email address to recover your account.") + " "} + {_t("Other users can invite you to rooms using your contact details.")} +
: null; + + const haveIs = Boolean(this.props.serverConfig.isUrl); + const noIsText = haveIs ? null :
+ {_t( + "No Identity Server is configured: no email addreses can be added. " + + "You will be unable to reset your password.", + )} +
; + return (

@@ -565,8 +598,8 @@ module.exports = React.createClass({ {this.renderEmail()} {this.renderPhoneNumber()}

- {_t("Use an email address to recover your account.") + " "} - {_t("Other users can invite you to rooms using your contact details.")} + { emailHelperText } + { noIsText } { registerButton } diff --git a/src/components/views/auth/ServerConfig.js b/src/components/views/auth/ServerConfig.js index 9dcc2c9abe8..467ba307d0b 100644 --- a/src/components/views/auth/ServerConfig.js +++ b/src/components/views/auth/ServerConfig.js @@ -210,7 +210,7 @@ export default class ServerConfig extends React.PureComponent { ": "Create your Matrix account on ", "Use an email address to recover your account.": "Use an email address to recover your account.", "Other users can invite you to rooms using your contact details.": "Other users can invite you to rooms using your contact details.", + "No Identity Server is configured: no email addreses can be added. You will be unable to reset your password.": "No Identity Server is configured: no email addreses can be added. You will be unable to reset your password.", "Other servers": "Other servers", "Enter custom server URLs What does this mean?": "Enter custom server URLs What does this mean?", "Homeserver URL": "Homeserver URL", diff --git a/src/utils/AutoDiscoveryUtils.js b/src/utils/AutoDiscoveryUtils.js index c21377a034a..e94c454a3e5 100644 --- a/src/utils/AutoDiscoveryUtils.js +++ b/src/utils/AutoDiscoveryUtils.js @@ -18,6 +18,7 @@ import React from 'react'; import {AutoDiscovery} from "matrix-js-sdk"; import {_t, _td, newTranslatableError} from "../languageHandler"; import {makeType} from "./TypeUtils"; +import SdkConfig from '../SdkConfig'; const LIVELINESS_DISCOVERY_ERRORS = [ AutoDiscovery.ERROR_INVALID_HOMESERVER, @@ -133,11 +134,14 @@ export default class AutoDiscoveryUtils { "m.homeserver": { base_url: homeserverUrl, }, - "m.identity_server": { - base_url: identityUrl, - }, }; + if (identityUrl) { + wellknownConfig['m.identity_server'] = { + base_url: identityUrl, + }; + } + const result = await AutoDiscovery.fromDiscoveryConfig(wellknownConfig); const url = new URL(homeserverUrl); @@ -179,14 +183,16 @@ export default class AutoDiscoveryUtils { const hsResult = discoveryResult['m.homeserver']; const isResult = discoveryResult['m.identity_server']; + const defaultConfig = SdkConfig.get()["validated_server_config"]; + // Validate the identity server first because an invalid identity server causes // and invalid homeserver, which may not be picked up correctly. - // Note: In the cases where we rely on this pre-populated "https://vector.im" (namely + // Note: In the cases where we rely on the default IS from the config (namely // lack of identity server provided by the discovery method), we intentionally do not - // validate it. We already know the IS is an IS, and this helps some off-the-grid usage + // validate it. This has already been validated and this helps some off-the-grid usage // of Riot. - let preferredIdentityUrl = "https://vector.im"; + let preferredIdentityUrl = defaultConfig && defaultConfig['isUrl']; if (isResult && isResult.state === AutoDiscovery.SUCCESS) { preferredIdentityUrl = isResult["base_url"]; } else if (isResult && isResult.state !== AutoDiscovery.PROMPT) { From bcf53c6e335a376bf963104ea0feeb050a7a6129 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Aug 2019 11:41:00 +0100 Subject: [PATCH 2/5] Make invite work without an IS Also fix it so you can't try to invite a room ID to a room --- src/Lifecycle.js | 6 ++++-- src/RoomInvite.js | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/src/Lifecycle.js b/src/Lifecycle.js index cad876e0195..0ddb7e9aae5 100644 --- a/src/Lifecycle.js +++ b/src/Lifecycle.js @@ -251,7 +251,7 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) { */ export function getLocalStorageSessionVars() { const hsUrl = localStorage.getItem("mx_hs_url"); - const isUrl = localStorage.getItem("mx_is_url") || 'https://matrix.org'; + const isUrl = localStorage.getItem("mx_is_url"); const accessToken = localStorage.getItem("mx_access_token"); const userId = localStorage.getItem("mx_user_id"); const deviceId = localStorage.getItem("mx_device_id"); @@ -479,7 +479,9 @@ class AbortLoginAndRebuildStorage extends Error { } function _persistCredentialsToLocalStorage(credentials) { localStorage.setItem("mx_hs_url", credentials.homeserverUrl); - localStorage.setItem("mx_is_url", credentials.identityServerUrl); + if (credentials.identityServerUrl) { + localStorage.setItem("mx_is_url", credentials.identityServerUrl); + } localStorage.setItem("mx_user_id", credentials.userId); localStorage.setItem("mx_access_token", credentials.accessToken); localStorage.setItem("mx_is_guest", JSON.stringify(credentials.guest)); diff --git a/src/RoomInvite.js b/src/RoomInvite.js index 34b9635780c..cfea51100b5 100644 --- a/src/RoomInvite.js +++ b/src/RoomInvite.js @@ -42,11 +42,17 @@ function inviteMultipleToRoom(roomId, addrs) { export function showStartChatInviteDialog() { const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog"); + + const validAddressTypes = ['mx-user-id']; + if (MatrixClientPeg.get().getIdentityServerUrl()) { + validAddressTypes.push('email'); + } + Modal.createTrackedDialog('Start a chat', '', AddressPickerDialog, { title: _t('Start a chat'), description: _t("Who would you like to communicate with?"), placeholder: _t("Email, name or Matrix ID"), - validAddressTypes: ['mx-user-id', 'email'], + validAddressTypes, button: _t("Start Chat"), onFinished: _onStartChatFinished, }); @@ -54,11 +60,18 @@ export function showStartChatInviteDialog() { export function showRoomInviteDialog(roomId) { const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog"); + + const validAddressTypes = ['mx-user-id']; + if (MatrixClientPeg.get().getIdentityServerUrl()) { + validAddressTypes.push('email'); + } + Modal.createTrackedDialog('Chat Invite', '', AddressPickerDialog, { title: _t('Invite new room members'), description: _t('Who would you like to add to this room?'), button: _t('Send Invites'), placeholder: _t("Email, name or Matrix ID"), + validAddressTypes, onFinished: (shouldInvite, addrs) => { _onRoomInviteFinished(roomId, shouldInvite, addrs); }, From d31f1ea7f2004748a19cdd29a8051dcf076481c5 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Aug 2019 11:51:42 +0100 Subject: [PATCH 3/5] Disable addign threepids if no IS configured --- .../settings/tabs/user/GeneralUserSettingsTab.js | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js index 06c012c91e1..32dcf4721c5 100644 --- a/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/GeneralUserSettingsTab.js @@ -28,6 +28,7 @@ import AccessibleButton from "../../../elements/AccessibleButton"; import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog"; import PropTypes from "prop-types"; const PlatformPeg = require("../../../../../PlatformPeg"); +const MatrixClientPeg = require("../../../../../MatrixClientPeg"); const sdk = require('../../../../..'); const Modal = require("../../../../../Modal"); const dis = require("../../../../../dispatcher"); @@ -119,6 +120,14 @@ export default class GeneralUserSettingsTab extends React.Component { onFinished={this._onPasswordChanged} /> ); + const threepidSection = MatrixClientPeg.get().getIdentityServerUrl() ?
+ {_t("Email addresses")} + + + {_t("Phone numbers")} + +
: null; + return (
{_t("Account")} @@ -126,12 +135,7 @@ export default class GeneralUserSettingsTab extends React.Component { {_t("Set a new account password...")}

{passwordChangeForm} - - {_t("Email addresses")} - - - {_t("Phone numbers")} - + {threepidSection}
); } From 9fa5e01f2f8789ec2d8571ea3eb5d6fb2c5eb28c Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Aug 2019 13:30:52 +0100 Subject: [PATCH 4/5] Disable password reset if no ID server --- src/components/structures/auth/ForgotPassword.js | 16 ++++++++++++++++ src/i18n/strings/en_EN.json | 5 +++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/components/structures/auth/ForgotPassword.js b/src/components/structures/auth/ForgotPassword.js index a5ffc9f0085..0c1a8ec33d4 100644 --- a/src/components/structures/auth/ForgotPassword.js +++ b/src/components/structures/auth/ForgotPassword.js @@ -256,6 +256,22 @@ module.exports = React.createClass({ ; } + if (!this.props.serverConfig.isUrl) { + return
+

+ {yourMatrixAccountText} + {editLink} +

+ {_t( + "No identity server is configured: " + + "add one in server settings to reset your password.", + )} + + {_t('Sign in instead')} + +
; + } + return
{errorText} {serverDeadSection} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index b2f42afe9e6..a712ac18c7d 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -556,10 +556,10 @@ "Success": "Success", "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them": "Your password was successfully changed. You will not receive push notifications on other devices until you log back in to them", "Profile": "Profile", - "Account": "Account", - "Set a new account password...": "Set a new account password...", "Email addresses": "Email addresses", "Phone numbers": "Phone numbers", + "Account": "Account", + "Set a new account password...": "Set a new account password...", "Language and region": "Language and region", "Theme": "Theme", "Light theme": "Light theme", @@ -1565,6 +1565,7 @@ "Your password has been reset.": "Your password has been reset.", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.", "Return to login screen": "Return to login screen", + "No identity server is configured: add one in server settings to reset your password.": "No identity server is configured: add one in server settings to reset your password.", "Set a new password": "Set a new password", "Invalid homeserver discovery response": "Invalid homeserver discovery response", "Failed to get autodiscovery configuration from server": "Failed to get autodiscovery configuration from server", From c09f86f34706b5d7f5a1c913d9e361ce4cf0df29 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 7 Aug 2019 13:37:24 +0100 Subject: [PATCH 5/5] re-run i18n --- src/i18n/strings/en_EN.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a712ac18c7d..20539cf9ec2 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1557,15 +1557,15 @@ "Changing your password will reset any end-to-end encryption keys on all of your devices, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another device before resetting your password.": "Changing your password will reset any end-to-end encryption keys on all of your devices, making encrypted chat history unreadable. Set up Key Backup or export your room keys from another device before resetting your password.", "Your Matrix account on %(serverName)s": "Your Matrix account on %(serverName)s", "Your Matrix account on ": "Your Matrix account on ", + "No identity server is configured: add one in server settings to reset your password.": "No identity server is configured: add one in server settings to reset your password.", + "Sign in instead": "Sign in instead", "A verification email will be sent to your inbox to confirm setting your new password.": "A verification email will be sent to your inbox to confirm setting your new password.", "Send Reset Email": "Send Reset Email", - "Sign in instead": "Sign in instead", "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.": "An email has been sent to %(emailAddress)s. Once you've followed the link it contains, click below.", "I have verified my email address": "I have verified my email address", "Your password has been reset.": "Your password has been reset.", "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.": "You have been logged out of all devices and will no longer receive push notifications. To re-enable notifications, sign in again on each device.", "Return to login screen": "Return to login screen", - "No identity server is configured: add one in server settings to reset your password.": "No identity server is configured: add one in server settings to reset your password.", "Set a new password": "Set a new password", "Invalid homeserver discovery response": "Invalid homeserver discovery response", "Failed to get autodiscovery configuration from server": "Failed to get autodiscovery configuration from server",