Apply prettier formatting

This commit is contained in:
Michael Weimann 2022-12-12 12:24:14 +01:00
parent 1cac306093
commit 526645c791
No known key found for this signature in database
GPG key ID: 53F535A266BB9584
1576 changed files with 65385 additions and 62478 deletions

View file

@ -14,19 +14,19 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
import React, { ReactNode } from 'react';
import React, { ReactNode } from "react";
import { ConnectionError, MatrixError } from "matrix-js-sdk/src/http-api";
import classNames from "classnames";
import { logger } from "matrix-js-sdk/src/logger";
import { ISSOFlow, LoginFlow } from "matrix-js-sdk/src/@types/auth";
import { _t, _td } from '../../../languageHandler';
import Login from '../../../Login';
import SdkConfig from '../../../SdkConfig';
import { messageForResourceLimitError } from '../../../utils/ErrorUtils';
import { _t, _td } from "../../../languageHandler";
import Login from "../../../Login";
import SdkConfig from "../../../SdkConfig";
import { messageForResourceLimitError } from "../../../utils/ErrorUtils";
import AutoDiscoveryUtils from "../../../utils/AutoDiscoveryUtils";
import AuthPage from "../../views/auth/AuthPage";
import PlatformPeg from '../../../PlatformPeg';
import PlatformPeg from "../../../PlatformPeg";
import SettingsStore from "../../../settings/SettingsStore";
import { UIFeature } from "../../../settings/UIFeature";
import { IMatrixClientCreds } from "../../../MatrixClientPeg";
@ -37,8 +37,8 @@ import SSOButtons from "../../views/elements/SSOButtons";
import ServerPicker from "../../views/elements/ServerPicker";
import AuthBody from "../../views/auth/AuthBody";
import AuthHeader from "../../views/auth/AuthHeader";
import AccessibleButton from '../../views/elements/AccessibleButton';
import { ValidatedServerConfig } from '../../../utils/ValidatedServerConfig';
import AccessibleButton from "../../views/elements/AccessibleButton";
import { ValidatedServerConfig } from "../../../utils/ValidatedServerConfig";
// These are used in several places, and come from the js-sdk's autodiscovery
// stuff. We define them here so that they'll be picked up by i18n.
@ -122,7 +122,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
flows: null,
username: props.defaultUsername? props.defaultUsername: '',
username: props.defaultUsername ? props.defaultUsername : "",
phoneCountry: null,
phoneNumber: "",
@ -134,13 +134,13 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
// map from login step type to a function which will render a control
// letting you do that login type
this.stepRendererMap = {
'm.login.password': this.renderPasswordStep,
"m.login.password": this.renderPasswordStep,
// CAS and SSO are the same thing, modulo the url we link to
// eslint-disable-next-line @typescript-eslint/naming-convention
'm.login.cas': () => this.renderSsoStep("cas"),
"m.login.cas": () => this.renderSsoStep("cas"),
// eslint-disable-next-line @typescript-eslint/naming-convention
'm.login.sso': () => this.renderSsoStep("sso"),
"m.login.sso": () => this.renderSsoStep("sso"),
};
}
@ -153,7 +153,8 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
}
public componentDidUpdate(prevProps) {
if (prevProps.serverConfig.hsUrl !== this.props.serverConfig.hsUrl ||
if (
prevProps.serverConfig.hsUrl !== this.props.serverConfig.hsUrl ||
prevProps.serverConfig.isUrl !== this.props.serverConfig.isUrl
) {
// Ensure that we end up actually logging in to the right place
@ -197,91 +198,77 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
loginIncorrect: false,
});
this.loginLogic.loginViaPassword(
username, phoneCountry, phoneNumber, password,
).then((data) => {
this.setState({ serverIsAlive: true }); // it must be, we logged in.
this.props.onLoggedIn(data, password);
}, (error) => {
if (this.unmounted) {
return;
}
let errorText;
this.loginLogic.loginViaPassword(username, phoneCountry, phoneNumber, password).then(
(data) => {
this.setState({ serverIsAlive: true }); // it must be, we logged in.
this.props.onLoggedIn(data, password);
},
(error) => {
if (this.unmounted) {
return;
}
let errorText;
// Some error strings only apply for logging in
const usingEmail = username.indexOf("@") > 0;
if (error.httpStatus === 400 && usingEmail) {
errorText = _t('This homeserver does not support login using email address.');
} 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.",
),
'hs_blocked': _td(
"This homeserver has been blocked by its administrator.",
),
'': _td(
"This homeserver has exceeded one of its resource limits.",
),
},
);
const errorDetail = messageForResourceLimitError(
error.data.limit_type,
error.data.admin_contact,
{
'': _td("Please <a>contact your service administrator</a> to continue using this service."),
},
);
errorText = (
<div>
<div>{ errorTop }</div>
<div className="mx_Login_smallError">{ errorDetail }</div>
</div>
);
} else if (error.httpStatus === 401 || error.httpStatus === 403) {
if (error.errcode === 'M_USER_DEACTIVATED') {
errorText = _t('This account has been deactivated.');
} else if (SdkConfig.get("disable_custom_urls")) {
// Some error strings only apply for logging in
const usingEmail = username.indexOf("@") > 0;
if (error.httpStatus === 400 && usingEmail) {
errorText = _t("This homeserver does not support login using email address.");
} 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."),
"hs_blocked": _td("This homeserver has been blocked by its administrator."),
"": _td("This homeserver has exceeded one of its resource limits."),
});
const errorDetail = messageForResourceLimitError(error.data.limit_type, error.data.admin_contact, {
"": _td("Please <a>contact your service administrator</a> to continue using this service."),
});
errorText = (
<div>
<div>{ _t('Incorrect username and/or password.') }</div>
<div className="mx_Login_smallError">
{ _t(
'Please note you are logging into the %(hs)s server, not matrix.org.',
{ hs: this.props.serverConfig.hsName },
) }
</div>
<div>{errorTop}</div>
<div className="mx_Login_smallError">{errorDetail}</div>
</div>
);
} else if (error.httpStatus === 401 || error.httpStatus === 403) {
if (error.errcode === "M_USER_DEACTIVATED") {
errorText = _t("This account has been deactivated.");
} else if (SdkConfig.get("disable_custom_urls")) {
errorText = (
<div>
<div>{_t("Incorrect username and/or password.")}</div>
<div className="mx_Login_smallError">
{_t("Please note you are logging into the %(hs)s server, not matrix.org.", {
hs: this.props.serverConfig.hsName,
})}
</div>
</div>
);
} else {
errorText = _t("Incorrect username and/or password.");
}
} else {
errorText = _t('Incorrect username and/or password.');
// other errors, not specific to doing a password login
errorText = this.errorTextFromError(error);
}
} else {
// other errors, not specific to doing a password login
errorText = this.errorTextFromError(error);
}
this.setState({
busy: false,
busyLoggingIn: false,
errorText: errorText,
// 401 would be the sensible status code for 'incorrect password'
// but the login API gives a 403 https://matrix.org/jira/browse/SYN-744
// mentions this (although the bug is for UI auth which is not this)
// We treat both as an incorrect password
loginIncorrect: error.httpStatus === 401 || error.httpStatus === 403,
});
});
this.setState({
busy: false,
busyLoggingIn: false,
errorText: errorText,
// 401 would be the sensible status code for 'incorrect password'
// but the login API gives a 403 https://matrix.org/jira/browse/SYN-744
// mentions this (although the bug is for UI auth which is not this)
// We treat both as an incorrect password
loginIncorrect: error.httpStatus === 401 || error.httpStatus === 403,
});
},
);
};
onUsernameChanged = username => {
onUsernameChanged = (username) => {
this.setState({ username: username });
};
onUsernameBlur = async username => {
onUsernameBlur = async (username) => {
const doWellknownLookup = username[0] === "@";
this.setState({
username: username,
@ -290,7 +277,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
canTryLogin: true,
});
if (doWellknownLookup) {
const serverName = username.split(':').slice(1).join(':');
const serverName = username.split(":").slice(1).join(":");
try {
const result = await AutoDiscoveryUtils.validateServerName(serverName);
this.props.onServerConfigChange(result);
@ -328,34 +315,37 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
}
};
onPhoneCountryChanged = phoneCountry => {
onPhoneCountryChanged = (phoneCountry) => {
this.setState({ phoneCountry: phoneCountry });
};
onPhoneNumberChanged = phoneNumber => {
onPhoneNumberChanged = (phoneNumber) => {
this.setState({
phoneNumber: phoneNumber,
});
};
onRegisterClick = ev => {
onRegisterClick = (ev) => {
ev.preventDefault();
ev.stopPropagation();
this.props.onRegisterClick();
};
onTryRegisterClick = ev => {
const hasPasswordFlow = this.state.flows?.find(flow => flow.type === "m.login.password");
const ssoFlow = this.state.flows?.find(flow => flow.type === "m.login.sso" || flow.type === "m.login.cas");
onTryRegisterClick = (ev) => {
const hasPasswordFlow = this.state.flows?.find((flow) => flow.type === "m.login.password");
const ssoFlow = this.state.flows?.find((flow) => flow.type === "m.login.sso" || flow.type === "m.login.cas");
// If has no password flow but an SSO flow guess that the user wants to register with SSO.
// TODO: instead hide the Register button if registration is disabled by checking with the server,
// has no specific errCode currently and uses M_FORBIDDEN.
if (ssoFlow && !hasPasswordFlow) {
ev.preventDefault();
ev.stopPropagation();
const ssoKind = ssoFlow.type === 'm.login.sso' ? 'sso' : 'cas';
PlatformPeg.get().startSingleSignOn(this.loginLogic.createTemporaryClient(), ssoKind,
this.props.fragmentAfterLogin);
const ssoKind = ssoFlow.type === "m.login.sso" ? "sso" : "cas";
PlatformPeg.get().startSingleSignOn(
this.loginLogic.createTemporaryClient(),
ssoKind,
this.props.fragmentAfterLogin,
);
} else {
// Don't intercept - just go through to the register page
this.onRegisterClick(ev);
@ -364,9 +354,10 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
private async initLoginLogic({ hsUrl, isUrl }: ValidatedServerConfig) {
let isDefaultServer = false;
if (this.props.serverConfig.isDefault
&& hsUrl === this.props.serverConfig.hsUrl
&& isUrl === this.props.serverConfig.isUrl
if (
this.props.serverConfig.isDefault &&
hsUrl === this.props.serverConfig.hsUrl &&
isUrl === this.props.serverConfig.isUrl
) {
isDefaultServer = true;
}
@ -385,8 +376,7 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
// Do a quick liveliness check on the URLs
try {
const { warning } =
await AutoDiscoveryUtils.validateServerConfigWithStaticUrls(hsUrl, isUrl);
const { warning } = await AutoDiscoveryUtils.validateServerConfigWithStaticUrls(hsUrl, isUrl);
if (warning) {
this.setState({
...AutoDiscoveryUtils.authComponentStateForError(warning),
@ -405,32 +395,40 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
});
}
loginLogic.getFlows().then((flows) => {
// look for a flow where we understand all of the steps.
const supportedFlows = flows.filter(this.isSupportedFlow);
loginLogic
.getFlows()
.then(
(flows) => {
// look for a flow where we understand all of the steps.
const supportedFlows = flows.filter(this.isSupportedFlow);
if (supportedFlows.length > 0) {
if (supportedFlows.length > 0) {
this.setState({
flows: supportedFlows,
});
return;
}
// we got to the end of the list without finding a suitable flow.
this.setState({
errorText: _t(
"This homeserver doesn't offer any login flows which are supported by this client.",
),
});
},
(err) => {
this.setState({
errorText: this.errorTextFromError(err),
loginIncorrect: false,
canTryLogin: false,
});
},
)
.finally(() => {
this.setState({
flows: supportedFlows,
busy: false,
});
return;
}
// we got to the end of the list without finding a suitable flow.
this.setState({
errorText: _t("This homeserver doesn't offer any login flows which are supported by this client."),
});
}, (err) => {
this.setState({
errorText: this.errorTextFromError(err),
loginIncorrect: false,
canTryLogin: false,
});
}).finally(() => {
this.setState({
busy: false,
});
});
}
private isSupportedFlow = (flow: LoginFlow): boolean => {
@ -449,41 +447,55 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
errCode = "HTTP " + err.httpStatus;
}
let errorText: ReactNode = _t("There was a problem communicating with the homeserver, " +
"please try again later.") + (errCode ? " (" + errCode + ")" : "");
let errorText: ReactNode =
_t("There was a problem communicating with the homeserver, " + "please try again later.") +
(errCode ? " (" + errCode + ")" : "");
if (err instanceof ConnectionError) {
if (window.location.protocol === 'https:' &&
(this.props.serverConfig.hsUrl.startsWith("http:") ||
!this.props.serverConfig.hsUrl.startsWith("http"))
if (
window.location.protocol === "https:" &&
(this.props.serverConfig.hsUrl.startsWith("http:") || !this.props.serverConfig.hsUrl.startsWith("http"))
) {
errorText = <span>
{ _t("Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. " +
"Either use HTTPS or <a>enable unsafe scripts</a>.", {},
{
'a': (sub) => {
return <a
target="_blank"
rel="noreferrer noopener"
href="https://www.google.com/search?&q=enable%20unsafe%20scripts"
>
{ sub }
</a>;
},
}) }
</span>;
errorText = (
<span>
{_t(
"Can't connect to homeserver via HTTP when an HTTPS URL is in your browser bar. " +
"Either use HTTPS or <a>enable unsafe scripts</a>.",
{},
{
a: (sub) => {
return (
<a
target="_blank"
rel="noreferrer noopener"
href="https://www.google.com/search?&q=enable%20unsafe%20scripts"
>
{sub}
</a>
);
},
},
)}
</span>
);
} else {
errorText = <span>
{ _t("Can't connect to homeserver - please check your connectivity, ensure your " +
"<a>homeserver's SSL certificate</a> is trusted, and that a browser extension " +
"is not blocking requests.", {},
{
'a': (sub) =>
<a target="_blank" rel="noreferrer noopener" href={this.props.serverConfig.hsUrl}>
{ sub }
</a>,
}) }
</span>;
errorText = (
<span>
{_t(
"Can't connect to homeserver - please check your connectivity, ensure your " +
"<a>homeserver's SSL certificate</a> is trusted, and that a browser extension " +
"is not blocking requests.",
{},
{
a: (sub) => (
<a target="_blank" rel="noreferrer noopener" href={this.props.serverConfig.hsUrl}>
{sub}
</a>
),
},
)}
</span>
);
}
}
@ -494,18 +506,17 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
if (!this.state.flows) return null;
// this is the ideal order we want to show the flows in
const order = [
"m.login.password",
"m.login.sso",
];
const order = ["m.login.password", "m.login.sso"];
const flows = order.map(type => this.state.flows.find(flow => flow.type === type)).filter(Boolean);
return <React.Fragment>
{ flows.map(flow => {
const stepRenderer = this.stepRendererMap[flow.type];
return <React.Fragment key={flow.type}>{ stepRenderer() }</React.Fragment>;
}) }
</React.Fragment>;
const flows = order.map((type) => this.state.flows.find((flow) => flow.type === type)).filter(Boolean);
return (
<React.Fragment>
{flows.map((flow) => {
const stepRenderer = this.stepRendererMap[flow.type];
return <React.Fragment key={flow.type}>{stepRenderer()}</React.Fragment>;
})}
</React.Fragment>
);
}
private renderPasswordStep = () => {
@ -528,8 +539,8 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
);
};
private renderSsoStep = loginType => {
const flow = this.state.flows.find(flow => flow.type === "m.login." + loginType) as ISSOFlow;
private renderSsoStep = (loginType) => {
const flow = this.state.flows.find((flow) => flow.type === "m.login." + loginType) as ISSOFlow;
return (
<SSOButtons
@ -537,60 +548,65 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
flow={flow}
loginType={loginType}
fragmentAfterLogin={this.props.fragmentAfterLogin}
primary={!this.state.flows.find(flow => flow.type === "m.login.password")}
primary={!this.state.flows.find((flow) => flow.type === "m.login.password")}
/>
);
};
render() {
const loader = this.isBusy() && !this.state.busyLoggingIn ?
<div className="mx_Login_loader"><Spinner /></div> : null;
const loader =
this.isBusy() && !this.state.busyLoggingIn ? (
<div className="mx_Login_loader">
<Spinner />
</div>
) : null;
const errorText = this.state.errorText;
let errorTextSection;
if (errorText) {
errorTextSection = (
<div className="mx_Login_error">
{ errorText }
</div>
);
errorTextSection = <div className="mx_Login_error">{errorText}</div>;
}
let serverDeadSection;
if (!this.state.serverIsAlive) {
const classes = classNames({
"mx_Login_error": true,
"mx_Login_serverError": true,
"mx_Login_serverErrorNonFatal": !this.state.serverErrorIsFatal,
mx_Login_error: true,
mx_Login_serverError: true,
mx_Login_serverErrorNonFatal: !this.state.serverErrorIsFatal,
});
serverDeadSection = (
<div className={classes}>
{ this.state.serverDeadError }
</div>
);
serverDeadSection = <div className={classes}>{this.state.serverDeadError}</div>;
}
let footer;
if (this.props.isSyncing || this.state.busyLoggingIn) {
footer = <div className="mx_AuthBody_paddedFooter">
<div className="mx_AuthBody_paddedFooter_title">
<InlineSpinner w={20} h={20} />
{ this.props.isSyncing ? _t("Syncing...") : _t("Signing In...") }
footer = (
<div className="mx_AuthBody_paddedFooter">
<div className="mx_AuthBody_paddedFooter_title">
<InlineSpinner w={20} h={20} />
{this.props.isSyncing ? _t("Syncing...") : _t("Signing In...")}
</div>
{this.props.isSyncing && (
<div className="mx_AuthBody_paddedFooter_subtitle">
{_t("If you've joined lots of rooms, this might take a while")}
</div>
)}
</div>
{ this.props.isSyncing && <div className="mx_AuthBody_paddedFooter_subtitle">
{ _t("If you've joined lots of rooms, this might take a while") }
</div> }
</div>;
);
} else if (SettingsStore.getValue(UIFeature.Registration)) {
footer = (
<span className="mx_AuthBody_changeFlow">
{ _t("New? <a>Create account</a>", {}, {
a: sub =>
<AccessibleButton kind='link_inline' onClick={this.onTryRegisterClick}>
{ sub }
</AccessibleButton>,
}) }
{_t(
"New? <a>Create account</a>",
{},
{
a: (sub) => (
<AccessibleButton kind="link_inline" onClick={this.onTryRegisterClick}>
{sub}
</AccessibleButton>
),
},
)}
</span>
);
}
@ -600,17 +616,17 @@ export default class LoginComponent extends React.PureComponent<IProps, IState>
<AuthHeader disableLanguageSelector={this.props.isSyncing || this.state.busyLoggingIn} />
<AuthBody>
<h1>
{ _t('Sign in') }
{ loader }
{_t("Sign in")}
{loader}
</h1>
{ errorTextSection }
{ serverDeadSection }
{errorTextSection}
{serverDeadSection}
<ServerPicker
serverConfig={this.props.serverConfig}
onServerConfigChange={this.props.onServerConfigChange}
/>
{ this.renderLoginComponentForFlows() }
{ footer }
{this.renderLoginComponentForFlows()}
{footer}
</AuthBody>
</AuthPage>
);