diff --git a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
index 92ede334d0..0867cae6f4 100644
--- a/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
+++ b/src/async-components/views/dialogs/secretstorage/CreateSecretStorageDialog.js
@@ -55,6 +55,7 @@ function selectText(target) {
export default class CreateSecretStorageDialog extends React.PureComponent {
static propTypes = {
hasCancel: PropTypes.bool,
+ accountPassword: PropTypes.string,
};
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
// for /keys/device_signing/upload?
canUploadKeysWithPasswordOnly: null,
- accountPassword: '',
+ accountPassword: props.accountPassword,
accountPasswordCorrect: null,
// set if we are 'upgrading' encryption (making an SSSS store from
// an existing key backup secret).
diff --git a/src/components/structures/MatrixChat.js b/src/components/structures/MatrixChat.js
index b4b38d7617..133d74db45 100644
--- a/src/components/structures/MatrixChat.js
+++ b/src/components/structures/MatrixChat.js
@@ -256,6 +256,9 @@ export default createReactClass({
// logout page.
Lifecycle.loadSession({});
}
+
+ this._accountPassword = null;
+ this._accountPasswordTimer = null;
},
componentDidMount: function() {
@@ -352,6 +355,8 @@ export default createReactClass({
window.removeEventListener("focus", this.onFocus);
window.removeEventListener('resize', this.handleResize);
this.state.resizeNotifier.removeListener("middlePanelResized", this._dispatchTimelineResize);
+
+ if (this._accountPasswordTimer !== null) clearTimeout(this._accountPasswordTimer);
},
componentWillUpdate: function(props, state) {
@@ -1729,9 +1734,8 @@ export default createReactClass({
this.showScreen("forgot_password");
},
- onRegisterFlowComplete: function(credentials) {
- this.onUserCompletedLoginFlow();
- return this.onRegistered(credentials);
+ onRegisterFlowComplete: function(credentials, password) {
+ return this.onUserCompletedLoginFlow(credentials, password);
},
// returns a promise which resolves to the new MatrixClient
@@ -1822,7 +1826,14 @@ export default createReactClass({
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)
// which is enough to ask the server about account data.
const loggedIn = new Promise(resolve => {
@@ -1836,7 +1847,7 @@ export default createReactClass({
});
// Create and start the client in the background
- Lifecycle.setLoggedIn(credentials);
+ const setLoggedInPromise = Lifecycle.setLoggedIn(credentials);
await loggedIn;
const cli = MatrixClientPeg.get();
@@ -1865,6 +1876,8 @@ export default createReactClass({
} else {
this._onLoggedIn();
}
+
+ return setLoggedInPromise;
},
// complete security / e2e setup has finished
@@ -1896,6 +1909,7 @@ export default createReactClass({
view = (
);
} else if (this.state.view === VIEWS.POST_REGISTRATION) {
diff --git a/src/components/structures/auth/E2eSetup.js b/src/components/structures/auth/E2eSetup.js
index a5f4ff933b..29b4345761 100644
--- a/src/components/structures/auth/E2eSetup.js
+++ b/src/components/structures/auth/E2eSetup.js
@@ -22,6 +22,7 @@ import * as sdk from '../../../index';
export default class E2eSetup extends React.Component {
static propTypes = {
onFinished: PropTypes.func.isRequired,
+ accountPassword: PropTypes.string,
};
constructor() {
@@ -40,6 +41,7 @@ export default class E2eSetup extends React.Component {
diff --git a/src/components/structures/auth/Login.js b/src/components/structures/auth/Login.js
index 7bc2dbcbae..c8b2a1ea9c 100644
--- a/src/components/structures/auth/Login.js
+++ b/src/components/structures/auth/Login.js
@@ -58,6 +58,11 @@ export default createReactClass({
displayName: 'Login',
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,
// If true, the component will consider itself busy.
@@ -181,7 +186,7 @@ export default createReactClass({
username, phoneCountry, phoneNumber, password,
).then((data) => {
this.setState({serverIsAlive: true}); // it must be, we logged in.
- this.props.onLoggedIn(data);
+ this.props.onLoggedIn(data, password);
}, (error) => {
if (this._unmounted) {
return;
diff --git a/src/components/structures/auth/Registration.js b/src/components/structures/auth/Registration.js
index fdf2f51e00..171d3ada26 100644
--- a/src/components/structures/auth/Registration.js
+++ b/src/components/structures/auth/Registration.js
@@ -45,7 +45,13 @@ export default createReactClass({
displayName: 'Registration',
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,
+
clientSecret: PropTypes.string,
sessionId: PropTypes.string,
makeRegistrationUrl: PropTypes.func.isRequired,
@@ -348,7 +354,7 @@ export default createReactClass({
homeserverUrl: this.state.matrixClient.getHomeserverUrl(),
identityServerUrl: this.state.matrixClient.getIdentityServerUrl(),
accessToken: response.access_token,
- });
+ }, this.state.formVals.password);
this._setupPushers(cli);
// we're still busy until we get unmounted: don't show the registration form again