This operation requires additional authentication.
- {this._renderCurrentStage()}
- {error}
-
-
- {submitButton}
- {cancelButton}
+
+
);
diff --git a/src/components/views/login/InteractiveAuthEntryComponents.js b/src/components/views/login/InteractiveAuthEntryComponents.js
index ec184ca09f..e18e60d7bc 100644
--- a/src/components/views/login/InteractiveAuthEntryComponents.js
+++ b/src/components/views/login/InteractiveAuthEntryComponents.js
@@ -1,5 +1,6 @@
/*
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.
@@ -20,7 +21,7 @@ import sdk from '../../../index';
import MatrixClientPeg from '../../../MatrixClientPeg';
/* This file contains a collection of components which are used by the
- * InteractiveAuthDialog to prompt the user to enter the information needed
+ * InteractiveAuth to prompt the user to enter the information needed
* for an auth stage. (The intention is that they could also be used for other
* components, such as the registration flow).
*
@@ -32,10 +33,10 @@ import MatrixClientPeg from '../../../MatrixClientPeg';
* stageParams: params from the server for the stage being attempted
* errorText: error message from a previous attempt to authenticate
* submitAuthDict: a function which will be called with the new auth dict
- * setSubmitButtonEnabled: a function which will enable/disable the 'submit' button
+ * busy: a boolean indicating whether the auth logic is doing something
+ * the user needs to wait for.
*
* Each component may also provide the following functions (beyond the standard React ones):
- * onSubmitClick: handle a 'submit' button click
* focus: set the input focus appropriately in the form.
*/
@@ -48,12 +49,16 @@ export const PasswordAuthEntry = React.createClass({
propTypes: {
submitAuthDict: React.PropTypes.func.isRequired,
- setSubmitButtonEnabled: React.PropTypes.func.isRequired,
errorText: React.PropTypes.string,
+ // is the auth logic currently waiting for something to
+ // happen?
+ busy: React.PropTypes.bool,
},
- componentWillMount: function() {
- this.props.setSubmitButtonEnabled(false);
+ getInitialState: function() {
+ return {
+ passwordValid: false,
+ };
},
focus: function() {
@@ -62,7 +67,10 @@ export const PasswordAuthEntry = React.createClass({
}
},
- onSubmitClick: function() {
+ _onSubmit: function(e) {
+ e.preventDefault();
+ if (this.props.busy) return;
+
this.props.submitAuthDict({
type: PasswordAuthEntry.LOGIN_TYPE,
user: MatrixClientPeg.get().credentials.userId,
@@ -72,7 +80,9 @@ export const PasswordAuthEntry = React.createClass({
_onPasswordFieldChange: function(ev) {
// enable the submit button iff the password is non-empty
- this.props.setSubmitButtonEnabled(Boolean(ev.target.value));
+ this.setState({
+ passwordValid: Boolean(this.refs.passwordField.value),
+ });
},
render: function() {
@@ -82,16 +92,34 @@ export const PasswordAuthEntry = React.createClass({
passwordBoxClass = 'error';
}
+ let submitButtonOrSpinner;
+ if (this.props.busy) {
+ const Loader = sdk.getComponent("elements.Spinner");
+ submitButtonOrSpinner = ;
+ } else {
+ submitButtonOrSpinner = (
+
+ );
+ }
+
return (
To continue, please enter your password.
Password:
-
+
{this.props.errorText}
@@ -110,14 +138,9 @@ export const RecaptchaAuthEntry = React.createClass({
propTypes: {
submitAuthDict: React.PropTypes.func.isRequired,
stageParams: React.PropTypes.object.isRequired,
- setSubmitButtonEnabled: React.PropTypes.func.isRequired,
errorText: React.PropTypes.string,
},
- componentWillMount: function() {
- this.props.setSubmitButtonEnabled(false);
- },
-
_onCaptchaResponse: function(response) {
this.props.submitAuthDict({
type: RecaptchaAuthEntry.LOGIN_TYPE,
@@ -148,7 +171,6 @@ export const FallbackAuthEntry = React.createClass({
authSessionId: React.PropTypes.string.isRequired,
loginType: React.PropTypes.string.isRequired,
submitAuthDict: React.PropTypes.func.isRequired,
- setSubmitButtonEnabled: React.PropTypes.func.isRequired,
errorText: React.PropTypes.string,
},
@@ -156,7 +178,6 @@ export const FallbackAuthEntry = React.createClass({
// we have to make the user click a button, as browsers will block
// the popup if we open it immediately.
this._popupWindow = null;
- this.props.setSubmitButtonEnabled(true);
window.addEventListener("message", this._onReceiveMessage);
},
@@ -167,13 +188,12 @@ export const FallbackAuthEntry = React.createClass({
}
},
- onSubmitClick: function() {
+ _onShowFallbackClick: function() {
var url = MatrixClientPeg.get().getFallbackAuthUrl(
this.props.loginType,
this.props.authSessionId
);
this._popupWindow = window.open(url);
- this.props.setSubmitButtonEnabled(false);
},
_onReceiveMessage: function(event) {
@@ -188,7 +208,7 @@ export const FallbackAuthEntry = React.createClass({
render: function() {
return (
diff --git a/test/components/views/dialogs/InteractiveAuthDialog-test.js b/test/components/views/dialogs/InteractiveAuthDialog-test.js
index 35daace0f8..80f027ab44 100644
--- a/test/components/views/dialogs/InteractiveAuthDialog-test.js
+++ b/test/components/views/dialogs/InteractiveAuthDialog-test.js
@@ -67,16 +67,24 @@ describe('InteractiveAuthDialog', function () {
onFinished={onFinished}
/>, parentDiv);
- // at this point there should be a password box
- const passwordNode = ReactTestUtils.findRenderedDOMComponentWithTag(
+ // at this point there should be a password box and a submit button
+ const formNode = ReactTestUtils.findRenderedDOMComponentWithTag(dlg, "form");
+ const inputNodes = ReactTestUtils.scryRenderedDOMComponentsWithTag(
dlg, "input"
);
- expect(passwordNode.type).toEqual("password");
+ let passwordNode;
+ let submitNode;
+ for (const node of inputNodes) {
+ if (node.type == 'password') {
+ passwordNode = node;
+ } else if (node.type == 'submit') {
+ submitNode = node;
+ }
+ }
+ expect(passwordNode).toExist();
+ expect(submitNode).toExist();
// submit should be disabled
- const submitNode = ReactTestUtils.findRenderedDOMComponentWithClass(
- dlg, "mx_Dialog_primary"
- );
expect(submitNode.disabled).toBe(true);
// put something in the password box, and hit enter; that should
@@ -84,9 +92,7 @@ describe('InteractiveAuthDialog', function () {
passwordNode.value = "s3kr3t";
ReactTestUtils.Simulate.change(passwordNode);
expect(submitNode.disabled).toBe(false);
- ReactTestUtils.Simulate.keyDown(passwordNode, {
- key: "Enter", keyCode: 13, which: 13,
- });
+ ReactTestUtils.Simulate.submit(formNode, {});
expect(doRequest.callCount).toEqual(1);
expect(doRequest.calledWithExactly({
@@ -96,8 +102,10 @@ describe('InteractiveAuthDialog', function () {
user: "@user:id",
})).toBe(true);
- // the submit button should now be disabled (and be a spinner)
- expect(submitNode.disabled).toBe(true);
+ // there should now be a spinner
+ ReactTestUtils.findRenderedComponentWithType(
+ dlg, sdk.getComponent('elements.Spinner'),
+ );
// let the request complete
q.delay(1).then(() => {