Remove various remaining bits of ILAG flows

TypeScript helpfully pointed me towards this dead code, which has been floating
around unused for a while. If we want to bring back ILAG in the future, we can
always revive it from history.
pull/21833/head
J. Ryan Stinnett 2020-10-07 12:49:29 +01:00
parent 1b255e42c3
commit f2b72efe39
13 changed files with 40 additions and 877 deletions

View File

@ -7,7 +7,6 @@ src/components/structures/SearchBox.js
src/components/structures/UploadBar.js
src/components/views/avatars/MemberAvatar.js
src/components/views/create_room/RoomAlias.js
src/components/views/dialogs/SetPasswordDialog.js
src/components/views/elements/AddressSelector.js
src/components/views/elements/DirectorySearchBox.js
src/components/views/elements/MemberEventListSummary.js

View File

@ -1,50 +0,0 @@
/*
Copyright 2015, 2016 OpenMarket Ltd
Copyright 2017 Vector Creations 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.
*/
.mx_SetMxIdDialog .mx_Dialog_title {
padding-right: 40px;
}
.mx_SetMxIdDialog_input_group {
display: flex;
}
.mx_SetMxIdDialog_input {
border-radius: 3px;
border: 1px solid $input-border-color;
padding: 9px;
color: $primary-fg-color;
background-color: $primary-bg-color;
font-size: $font-15px;
width: 100%;
max-width: 280px;
}
.mx_SetMxIdDialog_input.error,
.mx_SetMxIdDialog_input.error:focus {
border: 1px solid $warning-color;
}
.mx_SetMxIdDialog_input_group .mx_Spinner {
height: 37px;
padding-left: 10px;
justify-content: flex-start;
}
.mx_SetMxIdDialog .success {
color: $accent-color;
}

View File

@ -1,34 +0,0 @@
/*
Copyright 2017 Vector Creations 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.
*/
.mx_SetPasswordDialog_change_password input {
border-radius: 3px;
border: 1px solid $input-border-color;
padding: 9px;
color: $primary-fg-color;
background-color: $primary-bg-color;
font-size: $font-15px;
max-width: 280px;
margin-bottom: 10px;
}
.mx_SetPasswordDialog_change_password_button {
margin-top: 68px;
}
.mx_SetPasswordDialog .mx_Dialog_content {
margin-bottom: 0px;
}

View File

@ -512,19 +512,8 @@ async function _doSetLoggedIn(
if (localStorage) {
try {
_persistCredentialsToLocalStorage(credentials);
// make sure we don't think that it's a fresh login any more
sessionStorage.removeItem("mx_fresh_login");
// The user registered as a PWLU (PassWord-Less User), the generated password
// is cached here such that the user can change it at a later time.
if (credentials.password) {
// Update SessionStore
dis.dispatch({
action: 'cached_password',
cachedPassword: credentials.password,
});
}
} catch (e) {
console.warn("Error using local storage: can't persist session!", e);
}

View File

@ -24,7 +24,6 @@ import dis from './dispatcher/dispatcher';
import * as sdk from './index';
import Modal from './Modal';
import { _t } from './languageHandler';
// import {MatrixClientPeg} from './MatrixClientPeg';
// Regex for what a "safe" or "Matrix-looking" localpart would be.
// TODO: Update as needed for https://github.com/matrix-org/matrix-doc/issues/1514
@ -44,70 +43,27 @@ export const SAFE_LOCALPART_REGEX = /^[a-z0-9=_\-./]+$/;
*/
export async function startAnyRegistrationFlow(options) {
if (options === undefined) options = {};
// look for an ILAG compatible flow. We define this as one
// which has only dummy or recaptcha flows. In practice it
// would support any stage InteractiveAuth supports, just not
// ones like email & msisdn which require the user to supply
// the relevant details in advance. We err on the side of
// caution though.
// XXX: ILAG is disabled for now,
// see https://github.com/vector-im/element-web/issues/8222
// const flows = await _getRegistrationFlows();
// const hasIlagFlow = flows.some((flow) => {
// return flow.stages.every((stage) => {
// return ['m.login.dummy', 'm.login.recaptcha', 'm.login.terms'].includes(stage);
// });
// });
// if (hasIlagFlow) {
// dis.dispatch({
// action: 'view_set_mxid',
// go_home_on_cancel: options.go_home_on_cancel,
// });
//} else {
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const modal = Modal.createTrackedDialog('Registration required', '', QuestionDialog, {
hasCancelButton: true,
quitOnly: true,
title: _t("Sign In or Create Account"),
description: _t("Use your account or create a new one to continue."),
button: _t("Create Account"),
extraButtons: [
<button key="start_login" onClick={() => {
modal.close();
dis.dispatch({action: 'start_login', screenAfterLogin: options.screen_after});
}}>{ _t('Sign In') }</button>,
],
onFinished: (proceed) => {
if (proceed) {
dis.dispatch({action: 'start_registration', screenAfterLogin: options.screen_after});
} else if (options.go_home_on_cancel) {
dis.dispatch({action: 'view_home_page'});
} else if (options.go_welcome_on_cancel) {
dis.dispatch({action: 'view_welcome_page'});
}
},
});
//}
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
const modal = Modal.createTrackedDialog('Registration required', '', QuestionDialog, {
hasCancelButton: true,
quitOnly: true,
title: _t("Sign In or Create Account"),
description: _t("Use your account or create a new one to continue."),
button: _t("Create Account"),
extraButtons: [
<button key="start_login" onClick={() => {
modal.close();
dis.dispatch({action: 'start_login', screenAfterLogin: options.screen_after});
}}>{ _t('Sign In') }</button>,
],
onFinished: (proceed) => {
if (proceed) {
dis.dispatch({action: 'start_registration', screenAfterLogin: options.screen_after});
} else if (options.go_home_on_cancel) {
dis.dispatch({action: 'view_home_page'});
} else if (options.go_welcome_on_cancel) {
dis.dispatch({action: 'view_welcome_page'});
}
},
});
}
// async function _getRegistrationFlows() {
// try {
// await MatrixClientPeg.get().register(
// null,
// null,
// undefined,
// {},
// {},
// );
// console.log("Register request succeeded when it should have returned 401!");
// } catch (e) {
// if (e.httpStatus === 401) {
// return e.data.flows;
// }
// throw e;
// }
// throw new Error("Register request succeeded when it should have returned 401!");
// }

View File

@ -27,7 +27,6 @@ import CallMediaHandler from '../../CallMediaHandler';
import { fixupColorFonts } from '../../utils/FontManager';
import * as sdk from '../../index';
import dis from '../../dispatcher/dispatcher';
import sessionStore from '../../stores/SessionStore';
import {MatrixClientPeg, IMatrixClientCreds} from '../../MatrixClientPeg';
import SettingsStore from "../../settings/SettingsStore";
@ -41,10 +40,6 @@ import HomePage from "./HomePage";
import ResizeNotifier from "../../utils/ResizeNotifier";
import PlatformPeg from "../../PlatformPeg";
import { DefaultTagID } from "../../stores/room-list/models";
import {
showToast as showSetPasswordToast,
hideToast as hideSetPasswordToast,
} from "../../toasts/SetPasswordToast";
import {
showToast as showServerLimitToast,
hideToast as hideServerLimitToast,
@ -149,8 +144,6 @@ class LoggedInView extends React.Component<IProps, IState> {
protected readonly _matrixClient: MatrixClient;
protected readonly _roomView: React.RefObject<any>;
protected readonly _resizeContainer: React.RefObject<ResizeHandle>;
protected readonly _sessionStore: sessionStore;
protected readonly _sessionStoreToken: { remove: () => void };
protected readonly _compactLayoutWatcherRef: string;
protected resizer: Resizer;
@ -171,12 +164,6 @@ class LoggedInView extends React.Component<IProps, IState> {
document.addEventListener('keydown', this._onNativeKeyDown, false);
this._sessionStore = sessionStore;
this._sessionStoreToken = this._sessionStore.addListener(
this._setStateFromSessionStore,
);
this._setStateFromSessionStore();
this._updateServerNoticeEvents();
this._matrixClient.on("accountData", this.onAccountData);
@ -205,9 +192,6 @@ class LoggedInView extends React.Component<IProps, IState> {
this._matrixClient.removeListener("sync", this.onSync);
this._matrixClient.removeListener("RoomState.events", this.onRoomStateEvents);
SettingsStore.unwatchSetting(this._compactLayoutWatcherRef);
if (this._sessionStoreToken) {
this._sessionStoreToken.remove();
}
this.resizer.detach();
}
@ -228,14 +212,6 @@ class LoggedInView extends React.Component<IProps, IState> {
return this._roomView.current.canResetTimeline();
};
_setStateFromSessionStore = () => {
if (this._sessionStore.getCachedPassword()) {
showSetPasswordToast();
} else {
hideSetPasswordToast();
}
};
_createResizer() {
const classNames = {
handle: "mx_ResizeHandle",

View File

@ -670,9 +670,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
case 'view_home_page':
this.viewHome();
break;
case 'view_set_mxid':
this.setMxId(payload);
break;
case 'view_start_chat_or_reuse':
this.chatCreateOrReuse(payload.user_id);
break;
@ -985,36 +982,6 @@ export default class MatrixChat extends React.PureComponent<IProps, IState> {
});
}
private setMxId(payload) {
const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog');
const close = Modal.createTrackedDialog('Set MXID', '', SetMxIdDialog, {
homeserverUrl: MatrixClientPeg.get().getHomeserverUrl(),
onFinished: (submitted, credentials) => {
if (!submitted) {
dis.dispatch({
action: 'cancel_after_sync_prepared',
});
if (payload.go_home_on_cancel) {
dis.dispatch({
action: 'view_home_page',
});
}
return;
}
MatrixClientPeg.setJustRegisteredUserId(credentials.user_id);
this.onRegistered(credentials);
},
onDifferentServerClicked: (ev) => {
dis.dispatch({action: 'start_registration'});
close();
},
onLoginClick: (ev) => {
dis.dispatch({action: 'start_login'});
close();
},
}).close;
}
private async createRoom(defaultPublic = false) {
const communityId = CommunityPrototypeStore.instance.getSelectedCommunityId();
if (communityId) {

View File

@ -1090,42 +1090,7 @@ export default class RoomView extends React.Component<IProps, IState> {
room_id: this.getRoomId(),
},
});
// Don't peek whilst registering otherwise getPendingEventList complains
// Do this by indicating our intention to join
// XXX: ILAG is disabled for now,
// see https://github.com/vector-im/element-web/issues/8222
dis.dispatch({action: 'require_registration'});
// dis.dispatch({
// action: 'will_join',
// });
// const SetMxIdDialog = sdk.getComponent('views.dialogs.SetMxIdDialog');
// const close = Modal.createTrackedDialog('Set MXID', '', SetMxIdDialog, {
// homeserverUrl: cli.getHomeserverUrl(),
// onFinished: (submitted, credentials) => {
// if (submitted) {
// this.props.onRegistered(credentials);
// } else {
// dis.dispatch({
// action: 'cancel_after_sync_prepared',
// });
// dis.dispatch({
// action: 'cancel_join',
// });
// }
// },
// onDifferentServerClicked: (ev) => {
// dis.dispatch({action: 'start_registration'});
// close();
// },
// onLoginClick: (ev) => {
// dis.dispatch({action: 'start_login'});
// close();
// },
// }).close;
// return;
} else {
Promise.resolve().then(() => {
const signUrl = this.props.threepidInvite?.signUrl;

View File

@ -1,304 +0,0 @@
/*
Copyright 2016 OpenMarket Ltd
Copyright 2017 Vector Creations 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 React, {createRef} from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import {MatrixClientPeg} from '../../../MatrixClientPeg';
import classnames from 'classnames';
import { Key } from '../../../Keyboard';
import { _t } from '../../../languageHandler';
import { SAFE_LOCALPART_REGEX } from '../../../Registration';
// The amount of time to wait for further changes to the input username before
// sending a request to the server
const USERNAME_CHECK_DEBOUNCE_MS = 250;
/*
* Prompt the user to set a display name.
*
* On success, `onFinished(true, newDisplayName)` is called.
*/
export default class SetMxIdDialog extends React.Component {
static propTypes = {
onFinished: PropTypes.func.isRequired,
// Called when the user requests to register with a different homeserver
onDifferentServerClicked: PropTypes.func.isRequired,
// Called if the user wants to switch to login instead
onLoginClick: PropTypes.func.isRequired,
};
constructor(props) {
super(props);
this._input_value = createRef();
this._uiAuth = createRef();
this.state = {
// The entered username
username: '',
// Indicate ongoing work on the username
usernameBusy: false,
// Indicate error with username
usernameError: '',
// Assume the homeserver supports username checking until "M_UNRECOGNIZED"
usernameCheckSupport: true,
// Whether the auth UI is currently being used
doingUIAuth: false,
// Indicate error with auth
authError: '',
};
}
componentDidMount() {
this._input_value.current.select();
this._matrixClient = MatrixClientPeg.get();
}
onValueChange = ev => {
this.setState({
username: ev.target.value,
usernameBusy: true,
usernameError: '',
}, () => {
if (!this.state.username || !this.state.usernameCheckSupport) {
this.setState({
usernameBusy: false,
});
return;
}
// Debounce the username check to limit number of requests sent
if (this._usernameCheckTimeout) {
clearTimeout(this._usernameCheckTimeout);
}
this._usernameCheckTimeout = setTimeout(() => {
this._doUsernameCheck().finally(() => {
this.setState({
usernameBusy: false,
});
});
}, USERNAME_CHECK_DEBOUNCE_MS);
});
};
onKeyUp = ev => {
if (ev.key === Key.ENTER) {
this.onSubmit();
}
};
onSubmit = ev => {
if (this._uiAuth.current) {
this._uiAuth.current.tryContinue();
}
this.setState({
doingUIAuth: true,
});
};
_doUsernameCheck() {
// We do a quick check ahead of the username availability API to ensure the
// user ID roughly looks okay from a Matrix perspective.
if (!SAFE_LOCALPART_REGEX.test(this.state.username)) {
this.setState({
usernameError: _t("A username can only contain lower case letters, numbers and '=_-./'"),
});
return Promise.reject();
}
// Check if username is available
return this._matrixClient.isUsernameAvailable(this.state.username).then(
(isAvailable) => {
if (isAvailable) {
this.setState({usernameError: ''});
}
},
(err) => {
// Indicate whether the homeserver supports username checking
const newState = {
usernameCheckSupport: err.errcode !== "M_UNRECOGNIZED",
};
console.error('Error whilst checking username availability: ', err);
switch (err.errcode) {
case "M_USER_IN_USE":
newState.usernameError = _t('Username not available');
break;
case "M_INVALID_USERNAME":
newState.usernameError = _t(
'Username invalid: %(errMessage)s',
{ errMessage: err.message},
);
break;
case "M_UNRECOGNIZED":
// This homeserver doesn't support username checking, assume it's
// fine and rely on the error appearing in registration step.
newState.usernameError = '';
break;
case undefined:
newState.usernameError = _t('Something went wrong!');
break;
default:
newState.usernameError = _t(
'An error occurred: %(error_string)s',
{ error_string: err.message },
);
break;
}
this.setState(newState);
},
);
}
_generatePassword() {
return Math.random().toString(36).slice(2);
}
_makeRegisterRequest = auth => {
// Not upgrading - changing mxids
const guestAccessToken = null;
if (!this._generatedPassword) {
this._generatedPassword = this._generatePassword();
}
return this._matrixClient.register(
this.state.username,
this._generatedPassword,
undefined, // session id: included in the auth dict already
auth,
{},
guestAccessToken,
);
};
_onUIAuthFinished = (success, response) => {
this.setState({
doingUIAuth: false,
});
if (!success) {
this.setState({ authError: response.message });
return;
}
this.props.onFinished(true, {
userId: response.user_id,
deviceId: response.device_id,
homeserverUrl: this._matrixClient.getHomeserverUrl(),
identityServerUrl: this._matrixClient.getIdentityServerUrl(),
accessToken: response.access_token,
password: this._generatedPassword,
});
};
render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const InteractiveAuth = sdk.getComponent('structures.InteractiveAuth');
let auth;
if (this.state.doingUIAuth) {
auth = <InteractiveAuth
matrixClient={this._matrixClient}
makeRequest={this._makeRegisterRequest}
onAuthFinished={this._onUIAuthFinished}
inputs={{}}
poll={true}
ref={this._uiAuth}
continueIsManaged={true}
/>;
}
const inputClasses = classnames({
"mx_SetMxIdDialog_input": true,
"error": Boolean(this.state.usernameError),
});
let usernameIndicator = null;
if (this.state.usernameBusy) {
usernameIndicator = <div>{_t("Checking...")}</div>;
} else {
const usernameAvailable = this.state.username &&
this.state.usernameCheckSupport && !this.state.usernameError;
const usernameIndicatorClasses = classnames({
"error": Boolean(this.state.usernameError),
"success": usernameAvailable,
});
usernameIndicator = <div className={usernameIndicatorClasses} role="alert">
{ usernameAvailable ? _t('Username available') : this.state.usernameError }
</div>;
}
let authErrorIndicator = null;
if (this.state.authError) {
authErrorIndicator = <div className="error" role="alert">
{ this.state.authError }
</div>;
}
const canContinue = this.state.username &&
!this.state.usernameError &&
!this.state.usernameBusy;
return (
<BaseDialog className="mx_SetMxIdDialog"
onFinished={this.props.onFinished}
title={_t('To get started, please pick a username!')}
contentId='mx_Dialog_content'
>
<div className="mx_Dialog_content" id='mx_Dialog_content'>
<div className="mx_SetMxIdDialog_input_group">
<input type="text" ref={this._input_value} value={this.state.username}
autoFocus={true}
onChange={this.onValueChange}
onKeyUp={this.onKeyUp}
size="30"
className={inputClasses}
/>
</div>
{ usernameIndicator }
<p>
{ _t(
'This will be your account name on the <span></span> ' +
'homeserver, or you can pick a <a>different server</a>.',
{},
{
'span': <span>{ this.props.homeserverUrl }</span>,
'a': (sub) => <a href="#" onClick={this.props.onDifferentServerClicked}>{ sub }</a>,
},
) }
</p>
<p>
{ _t(
'If you already have a Matrix account you can <a>log in</a> instead.',
{},
{ 'a': (sub) => <a href="#" onClick={this.props.onLoginClick}>{ sub }</a> },
) }
</p>
{ auth }
{ authErrorIndicator }
</div>
<div className="mx_Dialog_buttons">
<input className="mx_Dialog_primary"
type="submit"
value={_t("Continue")}
onClick={this.onSubmit}
disabled={!canContinue}
/>
</div>
</BaseDialog>
);
}
}

View File

@ -1,130 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Copyright 2018 New Vector Ltd
Copyright 2019 Michael Telatynski <7t3chguy@gmail.com>
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 React from 'react';
import PropTypes from 'prop-types';
import * as sdk from '../../../index';
import { _t } from '../../../languageHandler';
import Modal from '../../../Modal';
const WarmFuzzy = function(props) {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
let title = _t('You have successfully set a password!');
if (props.didSetEmail) {
title = _t('You have successfully set a password and an email address!');
}
const advice = _t('You can now return to your account after signing out, and sign in on other devices.');
let extraAdvice = null;
if (!props.didSetEmail) {
extraAdvice = _t('Remember, you can always set an email address in user settings if you change your mind.');
}
return <BaseDialog className="mx_SetPasswordDialog"
onFinished={props.onFinished}
title={ title }
>
<div className="mx_Dialog_content">
<p>
{ advice }
</p>
<p>
{ extraAdvice }
</p>
</div>
<div className="mx_Dialog_buttons">
<button
className="mx_Dialog_primary"
autoFocus={true}
onClick={props.onFinished}>
{ _t('Continue') }
</button>
</div>
</BaseDialog>;
};
/**
* Prompt the user to set a password
*
* On success, `onFinished()` when finished
*/
export default class SetPasswordDialog extends React.Component {
static propTypes = {
onFinished: PropTypes.func.isRequired,
};
state = {
error: null,
};
_onPasswordChanged = res => {
Modal.createDialog(WarmFuzzy, {
didSetEmail: res.didSetEmail,
onFinished: () => {
this.props.onFinished();
},
});
};
_onPasswordChangeError = err => {
let errMsg = err.error || "";
if (err.httpStatus === 403) {
errMsg = _t('Failed to change password. Is your password correct?');
} else if (err.httpStatus) {
errMsg += ' ' + _t(
'(HTTP status %(httpStatus)s)',
{ httpStatus: err.httpStatus },
);
}
this.setState({
error: errMsg,
});
};
render() {
const BaseDialog = sdk.getComponent('views.dialogs.BaseDialog');
const ChangePassword = sdk.getComponent('views.settings.ChangePassword');
return (
<BaseDialog className="mx_SetPasswordDialog"
onFinished={this.props.onFinished}
title={ _t('Please set a password!') }
>
<div className="mx_Dialog_content">
<p>
{ _t('This will allow you to return to your account after signing out, and sign in on other sessions.') }
</p>
<ChangePassword
className="mx_SetPasswordDialog_change_password"
rowClassName=""
buttonClassNames="mx_Dialog_primary mx_SetPasswordDialog_change_password_button"
buttonKind="primary"
confirm={false}
autoFocusNewPasswordInput={true}
shouldAskForEmail={true}
onError={this._onPasswordChangeError}
onFinished={this._onPasswordChanged}
buttonLabel={_t("Set Password")}
/>
<div className="error">
{ this.state.error }
</div>
</div>
</BaseDialog>
);
}
}

View File

@ -19,14 +19,12 @@ import Field from "../elements/Field";
import React from 'react';
import PropTypes from 'prop-types';
import {MatrixClientPeg} from "../../../MatrixClientPeg";
import dis from "../../../dispatcher/dispatcher";
import AccessibleButton from '../elements/AccessibleButton';
import Spinner from '../elements/Spinner';
import { _t } from '../../../languageHandler';
import * as sdk from "../../../index";
import Modal from "../../../Modal";
import sessionStore from '../../../stores/SessionStore';
export default class ChangePassword extends React.Component {
static propTypes = {
onFinished: PropTypes.func,
@ -66,33 +64,11 @@ export default class ChangePassword extends React.Component {
state = {
phase: ChangePassword.Phases.Edit,
cachedPassword: null,
oldPassword: "",
newPassword: "",
newPasswordConfirm: "",
};
componentDidMount() {
this._sessionStore = sessionStore;
this._sessionStoreToken = this._sessionStore.addListener(
this._setStateFromSessionStore,
);
this._setStateFromSessionStore();
}
componentWillUnmount() {
if (this._sessionStoreToken) {
this._sessionStoreToken.remove();
}
}
_setStateFromSessionStore = () => {
this.setState({
cachedPassword: this._sessionStore.getCachedPassword(),
});
};
changePassword(oldPassword, newPassword) {
const cli = MatrixClientPeg.get();
@ -119,8 +95,11 @@ export default class ChangePassword extends React.Component {
</div>,
button: _t("Continue"),
extraButtons: [
<button className="mx_Dialog_primary"
onClick={this._onExportE2eKeysClicked}>
<button
key="exportRoomKeys"
className="mx_Dialog_primary"
onClick={this._onExportE2eKeysClicked}
>
{ _t('Export E2E room keys') }
</button>,
],
@ -150,9 +129,6 @@ export default class ChangePassword extends React.Component {
});
cli.setPassword(authDict, newPassword).then(() => {
// Notify SessionStore that the user's password was changed
dis.dispatch({action: 'password_changed'});
if (this.props.shouldAskForEmail) {
return this._optionallySetEmail().then((confirmed) => {
this.props.onFinished({
@ -212,7 +188,7 @@ export default class ChangePassword extends React.Component {
onClickChange = (ev) => {
ev.preventDefault();
const oldPassword = this.state.cachedPassword || this.state.oldPassword;
const oldPassword = this.state.oldPassword;
const newPassword = this.state.newPassword;
const confirmPassword = this.state.newPasswordConfirm;
const err = this.props.onCheckPassword(
@ -231,31 +207,22 @@ export default class ChangePassword extends React.Component {
const rowClassName = this.props.rowClassName;
const buttonClassName = this.props.buttonClassName;
let currentPassword = null;
if (!this.state.cachedPassword) {
currentPassword = (
<div className={rowClassName}>
<Field
type="password"
label={_t('Current password')}
value={this.state.oldPassword}
onChange={this.onChangeOldPassword}
/>
</div>
);
}
switch (this.state.phase) {
case ChangePassword.Phases.Edit:
const passwordLabel = this.state.cachedPassword ?
_t('Password') : _t('New Password');
return (
<form className={this.props.className} onSubmit={this.onClickChange}>
{ currentPassword }
<div className={rowClassName}>
<Field
type="password"
label={passwordLabel}
label={_t('Current password')}
value={this.state.oldPassword}
onChange={this.onChangeOldPassword}
/>
</div>
<div className={rowClassName}>
<Field
type="password"
label={_t('New Password')}
value={this.state.newPassword}
autoFocus={this.props.autoFocusNewPasswordInput}
onChange={this.onChangeNewPassword}
@ -277,10 +244,9 @@ export default class ChangePassword extends React.Component {
</form>
);
case ChangePassword.Phases.Uploading:
var Loader = sdk.getComponent("elements.Spinner");
return (
<div className="mx_Dialog_content">
<Loader />
<Spinner />
</div>
);
}

View File

@ -1,90 +0,0 @@
/*
Copyright 2017 Vector Creations Ltd
Copyright 2019 The Matrix.org Foundation C.I.C.
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 dis from '../dispatcher/dispatcher';
import {Store} from 'flux/utils';
const INITIAL_STATE = {
cachedPassword: localStorage.getItem('mx_pass'),
};
/**
* A class for storing application state to do with the session. This is a simple flux
* store that listens for actions and updates its state accordingly, informing any
* listeners (views) of state changes.
*
* Usage:
* ```
* sessionStore.addListener(() => {
* this.setState({ cachedPassword: sessionStore.getCachedPassword() })
* })
* ```
*/
class SessionStore extends Store {
constructor() {
super(dis);
// Initialise state
this._state = INITIAL_STATE;
}
_update() {
// Persist state to localStorage
if (this._state.cachedPassword) {
localStorage.setItem('mx_pass', this._state.cachedPassword);
} else {
localStorage.removeItem('mx_pass', this._state.cachedPassword);
}
this.__emitChange();
}
_setState(newState) {
this._state = Object.assign(this._state, newState);
this._update();
}
__onDispatch(payload) {
switch (payload.action) {
case 'cached_password':
this._setState({
cachedPassword: payload.cachedPassword,
});
break;
case 'password_changed':
this._setState({
cachedPassword: null,
});
break;
case 'on_client_not_viable':
case 'on_logged_out':
this._setState({
cachedPassword: null,
});
break;
}
}
getCachedPassword() {
return this._state.cachedPassword;
}
}
let singletonSessionStore = null;
if (!singletonSessionStore) {
singletonSessionStore = new SessionStore();
}
export default singletonSessionStore;

View File

@ -1,47 +0,0 @@
/*
Copyright 2020 The Matrix.org Foundation C.I.C.
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";
import Modal from "../Modal";
import SetPasswordDialog from "../components/views/dialogs/SetPasswordDialog";
import GenericToast from "../components/views/toasts/GenericToast";
import ToastStore from "../stores/ToastStore";
const onAccept = () => {
Modal.createTrackedDialog('Set Password Dialog', 'Password Nag Bar', SetPasswordDialog);
};
const TOAST_KEY = "setpassword";
export const showToast = () => {
ToastStore.sharedInstance().addOrReplaceToast({
key: TOAST_KEY,
title: _t("Set password"),
props: {
description: _t("To return to your account in future you need to set a password"),
acceptLabel: _t("Set Password"),
onAccept,
rejectLabel: _t("Later"),
onReject: hideToast, // it'll return on reload
},
component: GenericToast,
priority: 60,
});
};
export const hideToast = () => {
ToastStore.sharedInstance().dismissToast(TOAST_KEY);
};