mirror of
https://github.com/vector-im/element-web.git
synced 2024-11-17 14:05:04 +08:00
Merge pull request #3285 from matrix-org/dbkr/work_without_is
Work with no ID server set
This commit is contained in:
commit
54ca7b708e
@ -251,7 +251,7 @@ function _registerAsGuest(hsUrl, isUrl, defaultDeviceDisplayName) {
|
|||||||
*/
|
*/
|
||||||
export function getLocalStorageSessionVars() {
|
export function getLocalStorageSessionVars() {
|
||||||
const hsUrl = localStorage.getItem("mx_hs_url");
|
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 accessToken = localStorage.getItem("mx_access_token");
|
||||||
const userId = localStorage.getItem("mx_user_id");
|
const userId = localStorage.getItem("mx_user_id");
|
||||||
const deviceId = localStorage.getItem("mx_device_id");
|
const deviceId = localStorage.getItem("mx_device_id");
|
||||||
@ -479,7 +479,9 @@ class AbortLoginAndRebuildStorage extends Error { }
|
|||||||
|
|
||||||
function _persistCredentialsToLocalStorage(credentials) {
|
function _persistCredentialsToLocalStorage(credentials) {
|
||||||
localStorage.setItem("mx_hs_url", credentials.homeserverUrl);
|
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_user_id", credentials.userId);
|
||||||
localStorage.setItem("mx_access_token", credentials.accessToken);
|
localStorage.setItem("mx_access_token", credentials.accessToken);
|
||||||
localStorage.setItem("mx_is_guest", JSON.stringify(credentials.guest));
|
localStorage.setItem("mx_is_guest", JSON.stringify(credentials.guest));
|
||||||
|
@ -42,11 +42,17 @@ function inviteMultipleToRoom(roomId, addrs) {
|
|||||||
|
|
||||||
export function showStartChatInviteDialog() {
|
export function showStartChatInviteDialog() {
|
||||||
const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog");
|
const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog");
|
||||||
|
|
||||||
|
const validAddressTypes = ['mx-user-id'];
|
||||||
|
if (MatrixClientPeg.get().getIdentityServerUrl()) {
|
||||||
|
validAddressTypes.push('email');
|
||||||
|
}
|
||||||
|
|
||||||
Modal.createTrackedDialog('Start a chat', '', AddressPickerDialog, {
|
Modal.createTrackedDialog('Start a chat', '', AddressPickerDialog, {
|
||||||
title: _t('Start a chat'),
|
title: _t('Start a chat'),
|
||||||
description: _t("Who would you like to communicate with?"),
|
description: _t("Who would you like to communicate with?"),
|
||||||
placeholder: _t("Email, name or Matrix ID"),
|
placeholder: _t("Email, name or Matrix ID"),
|
||||||
validAddressTypes: ['mx-user-id', 'email'],
|
validAddressTypes,
|
||||||
button: _t("Start Chat"),
|
button: _t("Start Chat"),
|
||||||
onFinished: _onStartChatFinished,
|
onFinished: _onStartChatFinished,
|
||||||
});
|
});
|
||||||
@ -54,11 +60,18 @@ export function showStartChatInviteDialog() {
|
|||||||
|
|
||||||
export function showRoomInviteDialog(roomId) {
|
export function showRoomInviteDialog(roomId) {
|
||||||
const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog");
|
const AddressPickerDialog = sdk.getComponent("dialogs.AddressPickerDialog");
|
||||||
|
|
||||||
|
const validAddressTypes = ['mx-user-id'];
|
||||||
|
if (MatrixClientPeg.get().getIdentityServerUrl()) {
|
||||||
|
validAddressTypes.push('email');
|
||||||
|
}
|
||||||
|
|
||||||
Modal.createTrackedDialog('Chat Invite', '', AddressPickerDialog, {
|
Modal.createTrackedDialog('Chat Invite', '', AddressPickerDialog, {
|
||||||
title: _t('Invite new room members'),
|
title: _t('Invite new room members'),
|
||||||
description: _t('Who would you like to add to this room?'),
|
description: _t('Who would you like to add to this room?'),
|
||||||
button: _t('Send Invites'),
|
button: _t('Send Invites'),
|
||||||
placeholder: _t("Email, name or Matrix ID"),
|
placeholder: _t("Email, name or Matrix ID"),
|
||||||
|
validAddressTypes,
|
||||||
onFinished: (shouldInvite, addrs) => {
|
onFinished: (shouldInvite, addrs) => {
|
||||||
_onRoomInviteFinished(roomId, shouldInvite, addrs);
|
_onRoomInviteFinished(roomId, shouldInvite, addrs);
|
||||||
},
|
},
|
||||||
|
@ -256,6 +256,22 @@ module.exports = React.createClass({
|
|||||||
</a>;
|
</a>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!this.props.serverConfig.isUrl) {
|
||||||
|
return <div>
|
||||||
|
<h3>
|
||||||
|
{yourMatrixAccountText}
|
||||||
|
{editLink}
|
||||||
|
</h3>
|
||||||
|
{_t(
|
||||||
|
"No identity server is configured: " +
|
||||||
|
"add one in server settings to reset your password.",
|
||||||
|
)}
|
||||||
|
<a className="mx_AuthBody_changeFlow" onClick={this.onLoginClick} href="#">
|
||||||
|
{_t('Sign in instead')}
|
||||||
|
</a>
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
return <div>
|
return <div>
|
||||||
{errorText}
|
{errorText}
|
||||||
{serverDeadSection}
|
{serverDeadSection}
|
||||||
|
@ -91,14 +91,25 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
const self = this;
|
const self = this;
|
||||||
if (this.state.email == '') {
|
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");
|
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||||
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
Modal.createTrackedDialog('If you don\'t specify an email address...', '', QuestionDialog, {
|
||||||
title: _t("Warning!"),
|
title: _t("Warning!"),
|
||||||
description:
|
description: desc,
|
||||||
<div>
|
|
||||||
{ _t("If you don't specify an email address, you won't be able to reset your password. " +
|
|
||||||
"Are you sure?") }
|
|
||||||
</div>,
|
|
||||||
button: _t("Continue"),
|
button: _t("Continue"),
|
||||||
onFinished: function(confirmed) {
|
onFinished: function(confirmed) {
|
||||||
if (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() {
|
renderEmail() {
|
||||||
if (!this._authStepIsUsed('m.login.email.identity')) {
|
if (!this._showEmail()) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const Field = sdk.getComponent('elements.Field');
|
const Field = sdk.getComponent('elements.Field');
|
||||||
@ -473,7 +492,8 @@ module.exports = React.createClass({
|
|||||||
|
|
||||||
renderPhoneNumber() {
|
renderPhoneNumber() {
|
||||||
const threePidLogin = !SdkConfig.get().disable_3pid_login;
|
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;
|
return null;
|
||||||
}
|
}
|
||||||
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
|
const CountryDropdown = sdk.getComponent('views.auth.CountryDropdown');
|
||||||
@ -547,6 +567,19 @@ module.exports = React.createClass({
|
|||||||
<input className="mx_Login_submit" type="submit" value={_t("Register")} disabled={!this.props.canSubmit} />
|
<input className="mx_Login_submit" type="submit" value={_t("Register")} disabled={!this.props.canSubmit} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const emailHelperText = this._showEmail() ? <div>
|
||||||
|
{_t("Use an email address to recover your account.") + " "}
|
||||||
|
{_t("Other users can invite you to rooms using your contact details.")}
|
||||||
|
</div> : null;
|
||||||
|
|
||||||
|
const haveIs = Boolean(this.props.serverConfig.isUrl);
|
||||||
|
const noIsText = haveIs ? null : <div>
|
||||||
|
{_t(
|
||||||
|
"No Identity Server is configured: no email addreses can be added. " +
|
||||||
|
"You will be unable to reset your password.",
|
||||||
|
)}
|
||||||
|
</div>;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3>
|
<h3>
|
||||||
@ -565,8 +598,8 @@ module.exports = React.createClass({
|
|||||||
{this.renderEmail()}
|
{this.renderEmail()}
|
||||||
{this.renderPhoneNumber()}
|
{this.renderPhoneNumber()}
|
||||||
</div>
|
</div>
|
||||||
{_t("Use an email address to recover your account.") + " "}
|
{ emailHelperText }
|
||||||
{_t("Other users can invite you to rooms using your contact details.")}
|
{ noIsText }
|
||||||
{ registerButton }
|
{ registerButton }
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
@ -210,7 +210,7 @@ export default class ServerConfig extends React.PureComponent {
|
|||||||
<Field id="mx_ServerConfig_isUrl"
|
<Field id="mx_ServerConfig_isUrl"
|
||||||
label={_t("Identity Server URL")}
|
label={_t("Identity Server URL")}
|
||||||
placeholder={this.props.serverConfig.isUrl}
|
placeholder={this.props.serverConfig.isUrl}
|
||||||
value={this.state.isUrl}
|
value={this.state.isUrl || ''}
|
||||||
onBlur={this.onIdentityServerBlur}
|
onBlur={this.onIdentityServerBlur}
|
||||||
onChange={this.onIdentityServerChange}
|
onChange={this.onIdentityServerChange}
|
||||||
disabled={this.state.busy}
|
disabled={this.state.busy}
|
||||||
|
@ -28,6 +28,7 @@ import AccessibleButton from "../../../elements/AccessibleButton";
|
|||||||
import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog";
|
import DeactivateAccountDialog from "../../../dialogs/DeactivateAccountDialog";
|
||||||
import PropTypes from "prop-types";
|
import PropTypes from "prop-types";
|
||||||
const PlatformPeg = require("../../../../../PlatformPeg");
|
const PlatformPeg = require("../../../../../PlatformPeg");
|
||||||
|
const MatrixClientPeg = require("../../../../../MatrixClientPeg");
|
||||||
const sdk = require('../../../../..');
|
const sdk = require('../../../../..');
|
||||||
const Modal = require("../../../../../Modal");
|
const Modal = require("../../../../../Modal");
|
||||||
const dis = require("../../../../../dispatcher");
|
const dis = require("../../../../../dispatcher");
|
||||||
@ -119,6 +120,14 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||||||
onFinished={this._onPasswordChanged} />
|
onFinished={this._onPasswordChanged} />
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const threepidSection = MatrixClientPeg.get().getIdentityServerUrl() ? <div>
|
||||||
|
<span className="mx_SettingsTab_subheading">{_t("Email addresses")}</span>
|
||||||
|
<EmailAddresses />
|
||||||
|
|
||||||
|
<span className="mx_SettingsTab_subheading">{_t("Phone numbers")}</span>
|
||||||
|
<PhoneNumbers />
|
||||||
|
</div> : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx_SettingsTab_section mx_GeneralUserSettingsTab_accountSection">
|
<div className="mx_SettingsTab_section mx_GeneralUserSettingsTab_accountSection">
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Account")}</span>
|
<span className="mx_SettingsTab_subheading">{_t("Account")}</span>
|
||||||
@ -126,12 +135,7 @@ export default class GeneralUserSettingsTab extends React.Component {
|
|||||||
{_t("Set a new account password...")}
|
{_t("Set a new account password...")}
|
||||||
</p>
|
</p>
|
||||||
{passwordChangeForm}
|
{passwordChangeForm}
|
||||||
|
{threepidSection}
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Email addresses")}</span>
|
|
||||||
<EmailAddresses />
|
|
||||||
|
|
||||||
<span className="mx_SettingsTab_subheading">{_t("Phone numbers")}</span>
|
|
||||||
<PhoneNumbers />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -559,10 +559,10 @@
|
|||||||
"Success": "Success",
|
"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",
|
"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",
|
"Profile": "Profile",
|
||||||
"Account": "Account",
|
|
||||||
"Set a new account password...": "Set a new account password...",
|
|
||||||
"Email addresses": "Email addresses",
|
"Email addresses": "Email addresses",
|
||||||
"Phone numbers": "Phone numbers",
|
"Phone numbers": "Phone numbers",
|
||||||
|
"Account": "Account",
|
||||||
|
"Set a new account password...": "Set a new account password...",
|
||||||
"Language and region": "Language and region",
|
"Language and region": "Language and region",
|
||||||
"Theme": "Theme",
|
"Theme": "Theme",
|
||||||
"Light theme": "Light theme",
|
"Light theme": "Light theme",
|
||||||
@ -1393,6 +1393,7 @@
|
|||||||
"Change": "Change",
|
"Change": "Change",
|
||||||
"Sign in with": "Sign in with",
|
"Sign in with": "Sign in with",
|
||||||
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?",
|
"If you don't specify an email address, you won't be able to reset your password. Are you sure?": "If you don't specify an email address, you won't be able to reset your password. Are you sure?",
|
||||||
|
"No Identity Server is configured so you cannot add add an email address in order to reset your password in the future.": "No Identity Server is configured so you cannot add add an email address in order to reset your password in the future.",
|
||||||
"Use an email address to recover your account": "Use an email address to recover your account",
|
"Use an email address to recover your account": "Use an email address to recover your account",
|
||||||
"Enter email address (required on this homeserver)": "Enter email address (required on this homeserver)",
|
"Enter email address (required on this homeserver)": "Enter email address (required on this homeserver)",
|
||||||
"Doesn't look like a valid email address": "Doesn't look like a valid email address",
|
"Doesn't look like a valid email address": "Doesn't look like a valid email address",
|
||||||
@ -1414,6 +1415,7 @@
|
|||||||
"Create your Matrix account on <underlinedServerName />": "Create your Matrix account on <underlinedServerName />",
|
"Create your Matrix account on <underlinedServerName />": "Create your Matrix account on <underlinedServerName />",
|
||||||
"Use an email address to recover your account.": "Use an email address to recover your account.",
|
"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.",
|
"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",
|
"Other servers": "Other servers",
|
||||||
"Enter custom server URLs <a>What does this mean?</a>": "Enter custom server URLs <a>What does this mean?</a>",
|
"Enter custom server URLs <a>What does this mean?</a>": "Enter custom server URLs <a>What does this mean?</a>",
|
||||||
"Homeserver URL": "Homeserver URL",
|
"Homeserver URL": "Homeserver URL",
|
||||||
@ -1559,9 +1561,10 @@
|
|||||||
"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.",
|
"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 %(serverName)s": "Your Matrix account on %(serverName)s",
|
||||||
"Your Matrix account on <underlinedServerName />": "Your Matrix account on <underlinedServerName />",
|
"Your Matrix account on <underlinedServerName />": "Your Matrix account on <underlinedServerName />",
|
||||||
|
"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.",
|
"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",
|
"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.",
|
"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",
|
"I have verified my email address": "I have verified my email address",
|
||||||
"Your password has been reset.": "Your password has been reset.",
|
"Your password has been reset.": "Your password has been reset.",
|
||||||
|
@ -18,6 +18,7 @@ import React from 'react';
|
|||||||
import {AutoDiscovery} from "matrix-js-sdk";
|
import {AutoDiscovery} from "matrix-js-sdk";
|
||||||
import {_t, _td, newTranslatableError} from "../languageHandler";
|
import {_t, _td, newTranslatableError} from "../languageHandler";
|
||||||
import {makeType} from "./TypeUtils";
|
import {makeType} from "./TypeUtils";
|
||||||
|
import SdkConfig from '../SdkConfig';
|
||||||
|
|
||||||
const LIVELINESS_DISCOVERY_ERRORS = [
|
const LIVELINESS_DISCOVERY_ERRORS = [
|
||||||
AutoDiscovery.ERROR_INVALID_HOMESERVER,
|
AutoDiscovery.ERROR_INVALID_HOMESERVER,
|
||||||
@ -133,11 +134,14 @@ export default class AutoDiscoveryUtils {
|
|||||||
"m.homeserver": {
|
"m.homeserver": {
|
||||||
base_url: homeserverUrl,
|
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 result = await AutoDiscovery.fromDiscoveryConfig(wellknownConfig);
|
||||||
|
|
||||||
const url = new URL(homeserverUrl);
|
const url = new URL(homeserverUrl);
|
||||||
@ -179,14 +183,16 @@ export default class AutoDiscoveryUtils {
|
|||||||
const hsResult = discoveryResult['m.homeserver'];
|
const hsResult = discoveryResult['m.homeserver'];
|
||||||
const isResult = discoveryResult['m.identity_server'];
|
const isResult = discoveryResult['m.identity_server'];
|
||||||
|
|
||||||
|
const defaultConfig = SdkConfig.get()["validated_server_config"];
|
||||||
|
|
||||||
// Validate the identity server first because an invalid identity server causes
|
// Validate the identity server first because an invalid identity server causes
|
||||||
// and invalid homeserver, which may not be picked up correctly.
|
// 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
|
// 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.
|
// of Riot.
|
||||||
let preferredIdentityUrl = "https://vector.im";
|
let preferredIdentityUrl = defaultConfig && defaultConfig['isUrl'];
|
||||||
if (isResult && isResult.state === AutoDiscovery.SUCCESS) {
|
if (isResult && isResult.state === AutoDiscovery.SUCCESS) {
|
||||||
preferredIdentityUrl = isResult["base_url"];
|
preferredIdentityUrl = isResult["base_url"];
|
||||||
} else if (isResult && isResult.state !== AutoDiscovery.PROMPT) {
|
} else if (isResult && isResult.state !== AutoDiscovery.PROMPT) {
|
||||||
|
Loading…
Reference in New Issue
Block a user