diff --git a/src/Signup.js b/src/Signup.js
new file mode 100644
index 0000000000..ba91ff60b0
--- /dev/null
+++ b/src/Signup.js
@@ -0,0 +1,90 @@
+"use strict";
+var MatrixClientPeg = require("./MatrixClientPeg");
+var dis = require("./dispatcher");
+var q = require("q");
+
+class Register {
+
+}
+
+class Login {
+ constructor(hsUrl, isUrl) {
+ this._hsUrl = hsUrl;
+ this._isUrl = isUrl;
+ this._currentFlowIndex = 0;
+ this._flows = [];
+ }
+
+ getFlows() {
+ var self = this;
+ // feels a bit wrong to be clobbering the global client for something we
+ // don't even know if it'll work, but we'll leave this here for now to
+ // not complicate matters further. It would be nicer to isolate this
+ // logic entirely from the rest of the app though.
+ MatrixClientPeg.replaceUsingUrls(
+ this._hsUrl,
+ this._isUrl
+ );
+ return MatrixClientPeg.get().loginFlows().then(function(result) {
+ self._flows = result.flows;
+ self._currentFlowIndex = 0;
+ // technically the UI should display options for all flows for the
+ // user to then choose one, so return all the flows here.
+ return self._flows;
+ });
+ }
+
+ chooseFlow(flowIndex) {
+ this._currentFlowIndex = flowIndex;
+ }
+
+ getCurrentFlowStep() {
+ // technically the flow can have multiple steps, but no one does this
+ // for login so we can ignore it.
+ var flowStep = this._flows[this._currentFlowIndex];
+ return flowStep ? flowStep.type : null;
+ }
+
+ loginViaPassword(username, pass) {
+ var self = this;
+ var isEmail = username.indexOf("@") > 0;
+ var loginParams = {
+ password: pass
+ };
+ if (isEmail) {
+ loginParams.medium = 'email';
+ loginParams.address = username;
+ } else {
+ loginParams.user = username;
+ }
+
+ return MatrixClientPeg.get().login('m.login.password', loginParams).then(function(data) {
+ return q({
+ homeserverUrl: self._hsUrl,
+ identityServerUrl: self._isUrl,
+ userId: data.user_id,
+ accessToken: data.access_token
+ });
+ }, function(error) {
+ if (error.httpStatus == 400 && loginParams.medium) {
+ error.friendlyText = (
+ 'This Home Server does not support login using email address.'
+ );
+ }
+ else if (error.httpStatus === 403) {
+ error.friendlyText = (
+ 'Incorrect username and/or password.'
+ );
+ }
+ else {
+ error.friendlyText = (
+ 'There was a problem logging in. (HTTP ' + error.httpStatus + ")"
+ );
+ }
+ throw error;
+ });
+ }
+}
+
+module.exports.Register = Register;
+module.exports.Login = Login;
diff --git a/src/controllers/organisms/CasLogin.js b/src/components/login/CasLogin.js
similarity index 75%
rename from src/controllers/organisms/CasLogin.js
rename to src/components/login/CasLogin.js
index d84306e587..32116a3f76 100644
--- a/src/controllers/organisms/CasLogin.js
+++ b/src/components/login/CasLogin.js
@@ -16,10 +16,12 @@ limitations under the License.
'use strict';
-var MatrixClientPeg = require("../../MatrixClientPeg");
+var MatrixClientPeg = require("../MatrixClientPeg");
+var React = require('react');
var url = require("url");
-module.exports = {
+module.exports = React.createClass({
+ displayName: 'CasLogin',
onCasClicked: function(ev) {
var cli = MatrixClientPeg.get();
@@ -30,4 +32,12 @@ module.exports = {
window.location.href = casUrl;
},
-};
+ render: function() {
+ return (
+
+
+
+ );
+ }
+
+});
diff --git a/src/components/login/PasswordLogin.js b/src/components/login/PasswordLogin.js
new file mode 100644
index 0000000000..fabd71d67e
--- /dev/null
+++ b/src/components/login/PasswordLogin.js
@@ -0,0 +1,65 @@
+/*
+Copyright 2015 OpenMarket 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.
+*/
+
+var React = require('react');
+var ReactDOM = require('react-dom');
+
+/**
+ * A pure UI component which displays a username/password form.
+ */
+module.exports = React.createClass({displayName: 'PasswordLogin',
+ propTypes: {
+ onSubmit: React.PropTypes.func.isRequired // fn(username, password)
+ },
+
+ getInitialState: function() {
+ return {
+ username: "",
+ password: ""
+ };
+ },
+
+ onSubmitForm: function(ev) {
+ ev.preventDefault();
+ this.props.onSubmit(this.state.username, this.state.password);
+ },
+
+ onUsernameChanged: function(ev) {
+ this.setState({username: ev.target.value});
+ },
+
+ onPasswordChanged: function(ev) {
+ this.setState({password: ev.target.value});
+ },
+
+ render: function() {
+ return (
+
+
+
+ );
+ }
+});
\ No newline at end of file
diff --git a/src/controllers/molecules/ServerConfig.js b/src/controllers/molecules/ServerConfig.js
deleted file mode 100644
index 77fcb1d8c5..0000000000
--- a/src/controllers/molecules/ServerConfig.js
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
-Copyright 2015 OpenMarket 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.
-*/
-
-'use strict';
-
-var React = require("react");
-
-module.exports = {
- propTypes: {
- onHsUrlChanged: React.PropTypes.func,
- onIsUrlChanged: React.PropTypes.func,
- defaultHsUrl: React.PropTypes.string,
- defaultIsUrl: React.PropTypes.string
- },
-
- getDefaultProps: function() {
- return {
- onHsUrlChanged: function() {},
- onIsUrlChanged: function() {},
- defaultHsUrl: 'https://matrix.org/',
- defaultIsUrl: 'https://matrix.org/'
- };
- },
-
- getInitialState: function() {
- return {
- hs_url: this.props.defaultHsUrl,
- is_url: this.props.defaultIsUrl,
- original_hs_url: this.props.defaultHsUrl,
- original_is_url: this.props.defaultIsUrl,
- }
- },
-
- hsChanged: function(ev) {
- this.setState({hs_url: ev.target.value}, function() {
- this.props.onHsUrlChanged(this.state.hs_url);
- });
- },
-
- // XXX: horrible naming due to potential confusion between the word 'is' and the acronym 'IS'
- isChanged: function(ev) {
- this.setState({is_url: ev.target.value}, function() {
- this.props.onIsUrlChanged(this.state.is_url);
- });
- },
-
- getHsUrl: function() {
- return this.state.hs_url;
- },
-
- getIsUrl: function() {
- return this.state.is_url;
- },
-};
diff --git a/src/controllers/pages/MatrixChat.js b/src/controllers/pages/MatrixChat.js
index 4990a9488a..c2f0589688 100644
--- a/src/controllers/pages/MatrixChat.js
+++ b/src/controllers/pages/MatrixChat.js
@@ -295,7 +295,14 @@ module.exports = {
}
},
- onLoggedIn: function() {
+ onLoggedIn: function(credentials) {
+ if (credentials) { // registration doesn't do this yet
+ console.log("onLoggedIn => %s", credentials.userId);
+ MatrixClientPeg.replaceUsingAccessToken(
+ credentials.homeserverUrl, credentials.identityServerUrl,
+ credentials.userId, credentials.accessToken
+ );
+ }
this.setState({
screen: undefined,
logged_in: true
@@ -309,7 +316,8 @@ module.exports = {
var cli = MatrixClientPeg.get();
var self = this;
cli.on('sync', function(state) {
- if (self.sdkReady || state !== "PREPARED") { return; }
+ console.log("MatrixClient sync state => %s", state);
+ if (state !== "PREPARED") { return; }
self.sdkReady = true;
if (self.starting_room_alias) {
diff --git a/src/controllers/templates/Login.js b/src/controllers/templates/Login.js
deleted file mode 100644
index 3c3a40e53a..0000000000
--- a/src/controllers/templates/Login.js
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
-Copyright 2015 OpenMarket 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.
-*/
-
-'use strict';
-
-var MatrixClientPeg = require("../../MatrixClientPeg");
-var dis = require("../../dispatcher");
-
-module.exports = {
- getInitialState: function() {
- return {
- step: 'choose_hs',
- busy: false,
- currentStep: 0,
- totalSteps: 1
- };
- },
-
- setStep: function(step) {
- this.setState({ step: step, busy: false });
- },
-
- onHSChosen: function() {
- MatrixClientPeg.replaceUsingUrls(
- // XXX: why is the controller invoking methods from the view? :( -matthew
- this.getHsUrl(),
- this.getIsUrl()
- );
- this.setState({
- hs_url: this.getHsUrl(),
- is_url: this.getIsUrl(),
- });
- this.setStep("fetch_stages");
- var cli = MatrixClientPeg.get();
- this.setState({
- busy: true,
- errorText: "",
- });
- var self = this;
- cli.loginFlows().done(function(result) {
- self.setState({
- flows: result.flows,
- currentStep: 1,
- totalSteps: result.flows.length+1
- });
- self.setStep('stage_'+result.flows[0].type);
- }, function(error) {
- self.setStep("choose_hs");
- self.setState({errorText: 'Unable to contact the given home server'});
- });
- },
-
- onUserPassEntered: function(ev) {
- ev.preventDefault();
- this.setState({
- busy: true,
- errorText: "",
- });
- var self = this;
-
- var formVals = this.getFormVals();
-
- var loginParams = {
- password: formVals.password
- };
- if (formVals.username.indexOf('@') > 0) {
- loginParams.medium = 'email';
- loginParams.address = formVals.username;
- } else {
- loginParams.user = formVals.username;
- }
-
- MatrixClientPeg.get().login('m.login.password', loginParams).done(function(data) {
- MatrixClientPeg.replaceUsingAccessToken(
- self.state.hs_url, self.state.is_url,
- data.user_id, data.access_token
- );
- if (self.props.onLoggedIn) {
- self.props.onLoggedIn();
- }
- }, function(error) {
- self.setStep("stage_m.login.password");
- if (error.httpStatus == 400 && loginParams.medium) {
- self.setState({errorText: 'This Home Server does not support login using email address.'});
- }
- else if (error.httpStatus === 403) {
- self.setState({errorText: 'Incorrect username and/or password.'});
- }
- else {
- self.setState({
- errorText: 'There was a problem logging in. (HTTP ' + error.httpStatus + ")"
- });
- }
- });
- },
-
- showRegister: function(ev) {
- ev.preventDefault();
- dis.dispatch({
- action: 'start_registration'
- });
- }
-};