Merge branch 'develop' into gsouqet/ts-migration-1
This commit is contained in:
commit
efce2d16f1
313 changed files with 4352 additions and 2957 deletions
|
@ -26,7 +26,7 @@ export default class AuthPage extends React.PureComponent {
|
|||
return (
|
||||
<div className="mx_AuthPage">
|
||||
<div className="mx_AuthPage_modal">
|
||||
{this.props.children}
|
||||
{ this.props.children }
|
||||
</div>
|
||||
<AuthFooter />
|
||||
</div>
|
||||
|
|
|
@ -21,59 +21,68 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
|
|||
|
||||
const DIV_ID = 'mx_recaptcha';
|
||||
|
||||
interface IProps {
|
||||
sitePublicKey?: string;
|
||||
interface ICaptchaFormProps {
|
||||
sitePublicKey: string;
|
||||
onCaptchaResponse: (response: string) => void;
|
||||
}
|
||||
|
||||
interface IState {
|
||||
errorText: string;
|
||||
interface ICaptchaFormState {
|
||||
errorText?: string;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* A pure UI component which displays a captcha form.
|
||||
*/
|
||||
@replaceableComponent("views.auth.CaptchaForm")
|
||||
export default class CaptchaForm extends React.Component<IProps, IState> {
|
||||
private captchaWidgetId: string;
|
||||
private recaptchaContainer = createRef<HTMLDivElement>();
|
||||
export default class CaptchaForm extends React.Component<ICaptchaFormProps, ICaptchaFormState> {
|
||||
static defaultProps = {
|
||||
onCaptchaResponse: () => {},
|
||||
};
|
||||
|
||||
constructor(props) {
|
||||
private captchaWidgetId?: string;
|
||||
private recaptchaContainer = createRef<HTMLDivElement>();
|
||||
|
||||
constructor(props: ICaptchaFormProps) {
|
||||
super(props);
|
||||
|
||||
this.state = {
|
||||
errorText: null,
|
||||
errorText: undefined,
|
||||
};
|
||||
|
||||
CountlyAnalytics.instance.track("onboarding_grecaptcha_begin");
|
||||
}
|
||||
|
||||
public componentDidMount(): void {
|
||||
componentDidMount() {
|
||||
// Just putting a script tag into the returned jsx doesn't work, annoyingly,
|
||||
// so we do this instead.
|
||||
if (window.grecaptcha) { // TODO: Properly find the type of `grecaptcha`
|
||||
if (this.isRecaptchaReady()) {
|
||||
// already loaded
|
||||
this.onCaptchaLoaded();
|
||||
} else {
|
||||
console.log("Loading recaptcha script...");
|
||||
window.mx_on_recaptcha_loaded = () => {this.onCaptchaLoaded();};
|
||||
window.mxOnRecaptchaLoaded = () => { this.onCaptchaLoaded(); };
|
||||
const scriptTag = document.createElement('script');
|
||||
scriptTag.setAttribute(
|
||||
'src', `https://www.recaptcha.net/recaptcha/api.js?onload=mx_on_recaptcha_loaded&render=explicit`,
|
||||
'src', `https://www.recaptcha.net/recaptcha/api.js?onload=mxOnRecaptchaLoaded&render=explicit`,
|
||||
);
|
||||
this.recaptchaContainer.current.appendChild(scriptTag);
|
||||
}
|
||||
}
|
||||
|
||||
public componentWillUnmount(): void {
|
||||
componentWillUnmount() {
|
||||
this.resetRecaptcha();
|
||||
}
|
||||
|
||||
private renderRecaptcha(divId): void {
|
||||
if (!window.grecaptcha) {
|
||||
// Borrowed directly from: https://github.com/codeep/react-recaptcha-google/commit/e118fa5670fa268426969323b2e7fe77698376ba
|
||||
private isRecaptchaReady(): boolean {
|
||||
return typeof window !== "undefined" &&
|
||||
typeof global.grecaptcha !== "undefined" &&
|
||||
typeof global.grecaptcha.render === 'function';
|
||||
}
|
||||
|
||||
private renderRecaptcha(divId: string) {
|
||||
if (!this.isRecaptchaReady()) {
|
||||
console.error("grecaptcha not loaded!");
|
||||
throw new Error("Recaptcha did not load successfully");
|
||||
}
|
||||
|
@ -83,23 +92,23 @@ export default class CaptchaForm extends React.Component<IProps, IState> {
|
|||
console.error("No public key for recaptcha!");
|
||||
throw new Error(
|
||||
"This server has not supplied enough information for Recaptcha "
|
||||
+ "authentication");
|
||||
+ "authentication");
|
||||
}
|
||||
|
||||
console.info("Rendering to %s", divId);
|
||||
this.captchaWidgetId = window.grecaptcha.render(divId, {
|
||||
this.captchaWidgetId = global.grecaptcha.render(divId, {
|
||||
sitekey: publicKey,
|
||||
callback: this.props.onCaptchaResponse,
|
||||
});
|
||||
}
|
||||
|
||||
private resetRecaptcha(): void {
|
||||
private resetRecaptcha() {
|
||||
if (this.captchaWidgetId !== null) {
|
||||
window.grecaptcha.reset(this.captchaWidgetId);
|
||||
global.grecaptcha.reset(this.captchaWidgetId);
|
||||
}
|
||||
}
|
||||
|
||||
private onCaptchaLoaded(): void {
|
||||
private onCaptchaLoaded() {
|
||||
console.log("Loaded recaptcha script.");
|
||||
try {
|
||||
this.renderRecaptcha(DIV_ID);
|
||||
|
@ -116,7 +125,7 @@ export default class CaptchaForm extends React.Component<IProps, IState> {
|
|||
}
|
||||
}
|
||||
|
||||
public render(): React.ReactNode {
|
||||
render() {
|
||||
let error = null;
|
||||
if (this.state.errorText) {
|
||||
error = (
|
||||
|
@ -128,9 +137,9 @@ export default class CaptchaForm extends React.Component<IProps, IState> {
|
|||
|
||||
return (
|
||||
<div ref={this.recaptchaContainer}>
|
||||
<p>{_t(
|
||||
<p>{ _t(
|
||||
"This homeserver would like to make sure you are not a robot.",
|
||||
)}</p>
|
||||
) }</p>
|
||||
<div id={DIV_ID} />
|
||||
{ error }
|
||||
</div>
|
||||
|
|
|
@ -417,12 +417,12 @@ export class TermsAuthEntry extends React.Component<ITermsAuthEntryProps, ITerms
|
|||
if (this.props.showContinue !== false) {
|
||||
// XXX: button classes
|
||||
submitButton = <button className="mx_InteractiveAuthEntryComponents_termsSubmit mx_GeneralButton"
|
||||
onClick={this.trySubmit} disabled={!allChecked}>{_t("Accept")}</button>;
|
||||
onClick={this.trySubmit} disabled={!allChecked}>{ _t("Accept") }</button>;
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<p>{_t("Please review and accept the policies of this homeserver:")}</p>
|
||||
<p>{ _t("Please review and accept the policies of this homeserver:") }</p>
|
||||
{ checkboxes }
|
||||
{ errorSection }
|
||||
{ submitButton }
|
||||
|
@ -613,7 +613,7 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
|
|||
className="mx_InteractiveAuthEntryComponents_msisdnEntry"
|
||||
value={this.state.token}
|
||||
onChange={this.onTokenChange}
|
||||
aria-label={ _t("Code")}
|
||||
aria-label={_t("Code")}
|
||||
/>
|
||||
<br />
|
||||
<input type="submit" value={_t("Submit")}
|
||||
|
@ -621,7 +621,7 @@ export class MsisdnAuthEntry extends React.Component<IMsisdnAuthEntryProps, IMsi
|
|||
disabled={!enableSubmit}
|
||||
/>
|
||||
</form>
|
||||
{errorSection}
|
||||
{ errorSection }
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
@ -717,21 +717,21 @@ export class SSOAuthEntry extends React.Component<ISSOAuthEntryProps, ISSOAuthEn
|
|||
<AccessibleButton
|
||||
onClick={this.props.onCancel}
|
||||
kind={this.props.continueKind ? (this.props.continueKind + '_outline') : 'primary_outline'}
|
||||
>{_t("Cancel")}</AccessibleButton>
|
||||
>{ _t("Cancel") }</AccessibleButton>
|
||||
);
|
||||
if (this.state.phase === SSOAuthEntry.PHASE_PREAUTH) {
|
||||
continueButton = (
|
||||
<AccessibleButton
|
||||
onClick={this.onStartAuthClick}
|
||||
kind={this.props.continueKind || 'primary'}
|
||||
>{this.props.continueText || _t("Single Sign On")}</AccessibleButton>
|
||||
>{ this.props.continueText || _t("Single Sign On") }</AccessibleButton>
|
||||
);
|
||||
} else {
|
||||
continueButton = (
|
||||
<AccessibleButton
|
||||
onClick={this.onConfirmClick}
|
||||
kind={this.props.continueKind || 'primary'}
|
||||
>{this.props.continueText || _t("Confirm")}</AccessibleButton>
|
||||
>{ this.props.continueText || _t("Confirm") }</AccessibleButton>
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -753,8 +753,8 @@ export class SSOAuthEntry extends React.Component<ISSOAuthEntryProps, ISSOAuthEn
|
|||
return <React.Fragment>
|
||||
{ errorSection }
|
||||
<div className="mx_InteractiveAuthEntryComponents_sso_buttons">
|
||||
{cancelButton}
|
||||
{continueButton}
|
||||
{ cancelButton }
|
||||
{ continueButton }
|
||||
</div>
|
||||
</React.Fragment>;
|
||||
}
|
||||
|
@ -825,7 +825,7 @@ export class FallbackAuthEntry extends React.Component<IAuthEntryProps> {
|
|||
<a href="" ref={this.fallbackButton} onClick={this.onShowFallbackClick}>{
|
||||
_t("Start authentication")
|
||||
}</a>
|
||||
{errorSection}
|
||||
{ errorSection }
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -416,7 +416,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
kind="link"
|
||||
onClick={this.onForgotPasswordClick}
|
||||
>
|
||||
{_t("Forgot password?")}
|
||||
{ _t("Forgot password?") }
|
||||
</AccessibleButton>;
|
||||
}
|
||||
|
||||
|
@ -441,16 +441,16 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
disabled={this.props.disableSubmit}
|
||||
>
|
||||
<option key={LoginField.MatrixId} value={LoginField.MatrixId}>
|
||||
{_t('Username')}
|
||||
{ _t('Username') }
|
||||
</option>
|
||||
<option
|
||||
key={LoginField.Email}
|
||||
value={LoginField.Email}
|
||||
>
|
||||
{_t('Email address')}
|
||||
{ _t('Email address') }
|
||||
</option>
|
||||
<option key={LoginField.Password} value={LoginField.Password}>
|
||||
{_t('Phone')}
|
||||
{ _t('Phone') }
|
||||
</option>
|
||||
</Field>
|
||||
</div>
|
||||
|
@ -460,8 +460,8 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
return (
|
||||
<div>
|
||||
<form onSubmit={this.onSubmitForm}>
|
||||
{loginType}
|
||||
{loginField}
|
||||
{ loginType }
|
||||
{ loginField }
|
||||
<Field
|
||||
className={pwFieldClass}
|
||||
type="password"
|
||||
|
@ -474,7 +474,7 @@ export default class PasswordLogin extends React.PureComponent<IProps, IState> {
|
|||
onValidate={this.onPasswordValidate}
|
||||
ref={field => this[LoginField.Password] = field}
|
||||
/>
|
||||
{forgotPasswordJsx}
|
||||
{ forgotPasswordJsx }
|
||||
{ !this.props.busy && <input className="mx_Login_submit"
|
||||
type="submit"
|
||||
value={_t('Sign in')}
|
||||
|
|
|
@ -537,15 +537,15 @@ export default class RegistrationForm extends React.PureComponent<IProps, IState
|
|||
<div>
|
||||
<form onSubmit={this.onSubmit}>
|
||||
<div className="mx_AuthBody_fieldRow">
|
||||
{this.renderUsername()}
|
||||
{ this.renderUsername() }
|
||||
</div>
|
||||
<div className="mx_AuthBody_fieldRow">
|
||||
{this.renderPassword()}
|
||||
{this.renderPasswordConfirm()}
|
||||
{ this.renderPassword() }
|
||||
{ this.renderPasswordConfirm() }
|
||||
</div>
|
||||
<div className="mx_AuthBody_fieldRow">
|
||||
{this.renderEmail()}
|
||||
{this.renderPhoneNumber()}
|
||||
{ this.renderEmail() }
|
||||
{ this.renderPhoneNumber() }
|
||||
</div>
|
||||
{ emailHelperText }
|
||||
{ registerButton }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue