Remember password for e2e bootstrapping
Fixes https://github.com/vector-im/riot-web/issues/12046
This commit is contained in:
parent
988ae14d35
commit
437b45f8a6
5 changed files with 36 additions and 8 deletions
|
@ -55,6 +55,7 @@ function selectText(target) {
|
||||||
export default class CreateSecretStorageDialog extends React.PureComponent {
|
export default class CreateSecretStorageDialog extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
hasCancel: PropTypes.bool,
|
hasCancel: PropTypes.bool,
|
||||||
|
accountPassword: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
defaultProps = {
|
defaultProps = {
|
||||||
|
@ -82,7 +83,7 @@ export default class CreateSecretStorageDialog extends React.PureComponent {
|
||||||
// does the server offer a UI auth flow with just m.login.password
|
// does the server offer a UI auth flow with just m.login.password
|
||||||
// for /keys/device_signing/upload?
|
// for /keys/device_signing/upload?
|
||||||
canUploadKeysWithPasswordOnly: null,
|
canUploadKeysWithPasswordOnly: null,
|
||||||
accountPassword: '',
|
accountPassword: props.accountPassword,
|
||||||
accountPasswordCorrect: null,
|
accountPasswordCorrect: null,
|
||||||
// set if we are 'upgrading' encryption (making an SSSS store from
|
// set if we are 'upgrading' encryption (making an SSSS store from
|
||||||
// an existing key backup secret).
|
// an existing key backup secret).
|
||||||
|
|
|
@ -256,6 +256,9 @@ export default createReactClass({
|
||||||
// logout page.
|
// logout page.
|
||||||
Lifecycle.loadSession({});
|
Lifecycle.loadSession({});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this._accountPassword = null;
|
||||||
|
this._accountPasswordTimer = null;
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
@ -352,6 +355,8 @@ export default createReactClass({
|
||||||
window.removeEventListener("focus", this.onFocus);
|
window.removeEventListener("focus", this.onFocus);
|
||||||
window.removeEventListener('resize', this.handleResize);
|
window.removeEventListener('resize', this.handleResize);
|
||||||
this.state.resizeNotifier.removeListener("middlePanelResized", this._dispatchTimelineResize);
|
this.state.resizeNotifier.removeListener("middlePanelResized", this._dispatchTimelineResize);
|
||||||
|
|
||||||
|
if (this._accountPasswordTimer !== null) clearTimeout(this._accountPasswordTimer);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUpdate: function(props, state) {
|
componentWillUpdate: function(props, state) {
|
||||||
|
@ -1729,9 +1734,8 @@ export default createReactClass({
|
||||||
this.showScreen("forgot_password");
|
this.showScreen("forgot_password");
|
||||||
},
|
},
|
||||||
|
|
||||||
onRegisterFlowComplete: function(credentials) {
|
onRegisterFlowComplete: function(credentials, password) {
|
||||||
this.onUserCompletedLoginFlow();
|
return this.onUserCompletedLoginFlow(credentials, password);
|
||||||
return this.onRegistered(credentials);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// returns a promise which resolves to the new MatrixClient
|
// returns a promise which resolves to the new MatrixClient
|
||||||
|
@ -1822,7 +1826,14 @@ export default createReactClass({
|
||||||
this._loggedInView = ref;
|
this._loggedInView = ref;
|
||||||
},
|
},
|
||||||
|
|
||||||
async onUserCompletedLoginFlow(credentials) {
|
async onUserCompletedLoginFlow(credentials, password) {
|
||||||
|
this._accountPassword = password;
|
||||||
|
// self-destruct the password after 5mins
|
||||||
|
if (this._accountPasswordTimer !== null) clearTimeout(this._accountPasswordTimer);
|
||||||
|
this._accountPasswordTimer = setTimeout(() => {
|
||||||
|
this._accountPassword = null;
|
||||||
|
this._accountPasswordTimer = null;
|
||||||
|
}, 60 * 5 * 1000);
|
||||||
// Wait for the client to be logged in (but not started)
|
// Wait for the client to be logged in (but not started)
|
||||||
// which is enough to ask the server about account data.
|
// which is enough to ask the server about account data.
|
||||||
const loggedIn = new Promise(resolve => {
|
const loggedIn = new Promise(resolve => {
|
||||||
|
@ -1836,7 +1847,7 @@ export default createReactClass({
|
||||||
});
|
});
|
||||||
|
|
||||||
// Create and start the client in the background
|
// Create and start the client in the background
|
||||||
Lifecycle.setLoggedIn(credentials);
|
const setLoggedInPromise = Lifecycle.setLoggedIn(credentials);
|
||||||
await loggedIn;
|
await loggedIn;
|
||||||
|
|
||||||
const cli = MatrixClientPeg.get();
|
const cli = MatrixClientPeg.get();
|
||||||
|
@ -1865,6 +1876,8 @@ export default createReactClass({
|
||||||
} else {
|
} else {
|
||||||
this._onLoggedIn();
|
this._onLoggedIn();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return setLoggedInPromise;
|
||||||
},
|
},
|
||||||
|
|
||||||
// complete security / e2e setup has finished
|
// complete security / e2e setup has finished
|
||||||
|
@ -1896,6 +1909,7 @@ export default createReactClass({
|
||||||
view = (
|
view = (
|
||||||
<E2eSetup
|
<E2eSetup
|
||||||
onFinished={this.onCompleteSecurityE2eSetupFinished}
|
onFinished={this.onCompleteSecurityE2eSetupFinished}
|
||||||
|
accountPassword={this._accountPassword}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
} else if (this.state.view === VIEWS.POST_REGISTRATION) {
|
} else if (this.state.view === VIEWS.POST_REGISTRATION) {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import * as sdk from '../../../index';
|
||||||
export default class E2eSetup extends React.Component {
|
export default class E2eSetup extends React.Component {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
onFinished: PropTypes.func.isRequired,
|
onFinished: PropTypes.func.isRequired,
|
||||||
|
accountPassword: PropTypes.string,
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
|
@ -40,6 +41,7 @@ export default class E2eSetup extends React.Component {
|
||||||
<AsyncWrapper prom={this._createStorageDialogPromise}
|
<AsyncWrapper prom={this._createStorageDialogPromise}
|
||||||
hasCancel={false}
|
hasCancel={false}
|
||||||
onFinished={this.props.onFinished}
|
onFinished={this.props.onFinished}
|
||||||
|
accountPassword={this.props.accountPassword}
|
||||||
/>
|
/>
|
||||||
</AuthBody>
|
</AuthBody>
|
||||||
</AuthPage>
|
</AuthPage>
|
||||||
|
|
|
@ -58,6 +58,11 @@ export default createReactClass({
|
||||||
displayName: 'Login',
|
displayName: 'Login',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
// Called when the user has logged in. Params:
|
||||||
|
// - The object returned by the login API
|
||||||
|
// - The user's password, if applicable, (may be cached in memory for a
|
||||||
|
// short time so the user is not required to re-enter their password
|
||||||
|
// for operations like uploading cross-signing keys).
|
||||||
onLoggedIn: PropTypes.func.isRequired,
|
onLoggedIn: PropTypes.func.isRequired,
|
||||||
|
|
||||||
// If true, the component will consider itself busy.
|
// If true, the component will consider itself busy.
|
||||||
|
@ -181,7 +186,7 @@ export default createReactClass({
|
||||||
username, phoneCountry, phoneNumber, password,
|
username, phoneCountry, phoneNumber, password,
|
||||||
).then((data) => {
|
).then((data) => {
|
||||||
this.setState({serverIsAlive: true}); // it must be, we logged in.
|
this.setState({serverIsAlive: true}); // it must be, we logged in.
|
||||||
this.props.onLoggedIn(data);
|
this.props.onLoggedIn(data, password);
|
||||||
}, (error) => {
|
}, (error) => {
|
||||||
if (this._unmounted) {
|
if (this._unmounted) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -45,7 +45,13 @@ export default createReactClass({
|
||||||
displayName: 'Registration',
|
displayName: 'Registration',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
// Called when the user has logged in. Params:
|
||||||
|
// - object with userId, deviceId, homeserverUrl, identityServerUrl, accessToken
|
||||||
|
// - The user's password, if available and applicable (may be cached in memory
|
||||||
|
// for a short time so the user is not required to re-enter their password
|
||||||
|
// for operations like uploading cross-signing keys).
|
||||||
onLoggedIn: PropTypes.func.isRequired,
|
onLoggedIn: PropTypes.func.isRequired,
|
||||||
|
|
||||||
clientSecret: PropTypes.string,
|
clientSecret: PropTypes.string,
|
||||||
sessionId: PropTypes.string,
|
sessionId: PropTypes.string,
|
||||||
makeRegistrationUrl: PropTypes.func.isRequired,
|
makeRegistrationUrl: PropTypes.func.isRequired,
|
||||||
|
@ -348,7 +354,7 @@ export default createReactClass({
|
||||||
homeserverUrl: this.state.matrixClient.getHomeserverUrl(),
|
homeserverUrl: this.state.matrixClient.getHomeserverUrl(),
|
||||||
identityServerUrl: this.state.matrixClient.getIdentityServerUrl(),
|
identityServerUrl: this.state.matrixClient.getIdentityServerUrl(),
|
||||||
accessToken: response.access_token,
|
accessToken: response.access_token,
|
||||||
});
|
}, this.state.formVals.password);
|
||||||
|
|
||||||
this._setupPushers(cli);
|
this._setupPushers(cli);
|
||||||
// we're still busy until we get unmounted: don't show the registration form again
|
// we're still busy until we get unmounted: don't show the registration form again
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue