Merge branch 'vector' of github.com:matrix-org/matrix-react-sdk into user_settings
This commit is contained in:
commit
f17a9b14c2
11 changed files with 553 additions and 12 deletions
|
@ -24,7 +24,52 @@ var React = require("react");
|
||||||
// maps cannot pass through two stages).
|
// maps cannot pass through two stages).
|
||||||
var MatrixReactSdk = require("../../src/index");
|
var MatrixReactSdk = require("../../src/index");
|
||||||
|
|
||||||
React.render(
|
// Here, we do some crude URL analysis to allow
|
||||||
<MatrixReactSdk.MatrixChat />,
|
// deep-linking. We only support registration
|
||||||
|
// deep-links in this example.
|
||||||
|
function routeUrl(location) {
|
||||||
|
if (location.hash.indexOf('#/register') == 0) {
|
||||||
|
var hashparts = location.hash.split('?');
|
||||||
|
var params = {};
|
||||||
|
if (hashparts.length == 2) {
|
||||||
|
var pairs = hashparts[1].split('&');
|
||||||
|
for (var i = 0; i < pairs.length; ++i) {
|
||||||
|
var parts = pairs[i].split('=');
|
||||||
|
if (parts.length != 2) continue;
|
||||||
|
params[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
window.matrixChat.showScreen('register', params);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var loaded = false;
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
routeUrl(window.location);
|
||||||
|
loaded = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// This will be called whenever the SDK changes screens,
|
||||||
|
// so a web page can update the URL bar appropriately.
|
||||||
|
var onNewScreen = function(screen) {
|
||||||
|
if (!loaded) return;
|
||||||
|
window.location.hash = '#/'+screen;
|
||||||
|
}
|
||||||
|
|
||||||
|
// We use this to work out what URL the SDK should
|
||||||
|
// pass through when registering to allow the user to
|
||||||
|
// click back to the client having registered.
|
||||||
|
// It's up to us to recognise if we're loaded with
|
||||||
|
// this URL and tell MatrixClient to resume registration.
|
||||||
|
var makeRegistrationUrl = function() {
|
||||||
|
return window.location.protocol + '//' +
|
||||||
|
window.location.host +
|
||||||
|
window.location.pathname +
|
||||||
|
'#/register';
|
||||||
|
}
|
||||||
|
|
||||||
|
window.matrixChat = React.render(
|
||||||
|
<MatrixReactSdk.MatrixChat onNewScreen={onNewScreen} registrationUrl={makeRegistrationUrl()} />,
|
||||||
document.getElementById('matrixchat')
|
document.getElementById('matrixchat')
|
||||||
);
|
);
|
||||||
|
|
|
@ -37,6 +37,12 @@ module.exports = React.createClass({
|
||||||
mixins: [RoomViewController],
|
mixins: [RoomViewController],
|
||||||
|
|
||||||
render: function() {
|
render: function() {
|
||||||
|
if (!this.state.room) {
|
||||||
|
return (
|
||||||
|
<div />
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
var myUserId = MatrixClientPeg.get().credentials.userId;
|
var myUserId = MatrixClientPeg.get().credentials.userId;
|
||||||
if (this.state.room.currentState.members[myUserId].membership == 'invite') {
|
if (this.state.room.currentState.members[myUserId].membership == 'invite') {
|
||||||
if (this.state.joining) {
|
if (this.state.joining) {
|
||||||
|
|
|
@ -24,6 +24,7 @@ var RoomView = ComponentBroker.get('organisms/RoomView');
|
||||||
var RightPanel = ComponentBroker.get('organisms/RightPanel');
|
var RightPanel = ComponentBroker.get('organisms/RightPanel');
|
||||||
var Login = ComponentBroker.get('templates/Login');
|
var Login = ComponentBroker.get('templates/Login');
|
||||||
var UserSettings = ComponentBroker.get('organisms/UserSettings');
|
var UserSettings = ComponentBroker.get('organisms/UserSettings');
|
||||||
|
var Register = ComponentBroker.get('templates/Register');
|
||||||
|
|
||||||
var MatrixChatController = require("../../../../src/controllers/pages/MatrixChat");
|
var MatrixChatController = require("../../../../src/controllers/pages/MatrixChat");
|
||||||
|
|
||||||
|
@ -61,6 +62,14 @@ module.exports = React.createClass({
|
||||||
return (
|
return (
|
||||||
<Loader />
|
<Loader />
|
||||||
);
|
);
|
||||||
|
} else if (this.state.screen == 'register') {
|
||||||
|
return (
|
||||||
|
<Register onLoggedIn={this.onLoggedIn} clientSecret={this.state.register_client_secret}
|
||||||
|
sessionId={this.state.register_session_id} idSid={this.state.register_id_sid}
|
||||||
|
hsUrl={this.state.register_hs_url} isUrl={this.state.register_is_url}
|
||||||
|
registrationUrl={this.props.registrationUrl}
|
||||||
|
/>
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
return (
|
return (
|
||||||
<Login onLoggedIn={this.onLoggedIn} />
|
<Login onLoggedIn={this.onLoggedIn} />
|
||||||
|
|
|
@ -40,6 +40,7 @@ module.exports = React.createClass({
|
||||||
<h1>Please log in:</h1>
|
<h1>Please log in:</h1>
|
||||||
{this.componentForStep(this.state.step)}
|
{this.componentForStep(this.state.step)}
|
||||||
<div className="error">{this.state.errorText}</div>
|
<div className="error">{this.state.errorText}</div>
|
||||||
|
<a onClick={this.showRegister} href="#">Create a new account</a>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
55
skins/base/views/templates/Register.js
Normal file
55
skins/base/views/templates/Register.js
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
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');
|
||||||
|
|
||||||
|
var ComponentBroker = require("../../../../src/ComponentBroker");
|
||||||
|
|
||||||
|
var Loader = require("react-loader");
|
||||||
|
|
||||||
|
var RegisterController = require("../../../../src/controllers/templates/Register");
|
||||||
|
|
||||||
|
module.exports = React.createClass({
|
||||||
|
displayName: 'Register',
|
||||||
|
mixins: [RegisterController],
|
||||||
|
|
||||||
|
registerContent: function() {
|
||||||
|
if (this.state.busy) {
|
||||||
|
return (
|
||||||
|
<Loader />
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<h1>Create a new account:</h1>
|
||||||
|
{this.componentForStep(this.state.step)}
|
||||||
|
<div className="error">{this.state.errorText}</div>
|
||||||
|
<a onClick={this.showLogin} href="#">Sign in with existing account</a>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
render: function() {
|
||||||
|
return (
|
||||||
|
<div className="mx_Register">
|
||||||
|
{this.registerContent()}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
|
@ -85,6 +85,7 @@ require('../skins/base/views/molecules/MemberTile');
|
||||||
require('../skins/base/views/organisms/RoomList');
|
require('../skins/base/views/organisms/RoomList');
|
||||||
require('../skins/base/views/organisms/RoomView');
|
require('../skins/base/views/organisms/RoomView');
|
||||||
require('../skins/base/views/templates/Login');
|
require('../skins/base/views/templates/Login');
|
||||||
|
require('../skins/base/views/templates/Register');
|
||||||
require('../skins/base/views/organisms/Notifier');
|
require('../skins/base/views/organisms/Notifier');
|
||||||
require('../skins/base/views/organisms/CreateRoom');
|
require('../skins/base/views/organisms/CreateRoom');
|
||||||
require('../skins/base/views/molecules/UserSelector');
|
require('../skins/base/views/molecules/UserSelector');
|
||||||
|
|
|
@ -24,11 +24,13 @@ var matrixClient = null;
|
||||||
var localStorage = window.localStorage;
|
var localStorage = window.localStorage;
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
var hs_url = localStorage.getItem("mx_hs_url");
|
var hs_url = localStorage.getItem("mx_hs_url");
|
||||||
|
var is_url = localStorage.getItem("mx_is_url") || 'https://matrix.org';
|
||||||
var access_token = localStorage.getItem("mx_access_token");
|
var access_token = localStorage.getItem("mx_access_token");
|
||||||
var user_id = localStorage.getItem("mx_user_id");
|
var user_id = localStorage.getItem("mx_user_id");
|
||||||
if (access_token && user_id && hs_url) {
|
if (access_token && user_id && hs_url) {
|
||||||
matrixClient = Matrix.createClient({
|
matrixClient = Matrix.createClient({
|
||||||
baseUrl: hs_url,
|
baseUrl: hs_url,
|
||||||
|
idBaseUrl: is_url,
|
||||||
accessToken: access_token,
|
accessToken: access_token,
|
||||||
userId: user_id
|
userId: user_id
|
||||||
});
|
});
|
||||||
|
@ -44,8 +46,11 @@ module.exports = {
|
||||||
matrixClient = cli;
|
matrixClient = cli;
|
||||||
},
|
},
|
||||||
|
|
||||||
replaceUsingUrl: function(hs_url) {
|
replaceUsingUrls: function(hs_url, is_url) {
|
||||||
matrixClient = Matrix.createClient(hs_url);
|
matrixClient = Matrix.createClient({
|
||||||
|
baseUrl: hs_url,
|
||||||
|
idBaseUrl: is_url
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ var tileTypes = {
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getInitialState: function() {
|
getInitialState: function() {
|
||||||
return {
|
return {
|
||||||
room: MatrixClientPeg.get().getRoom(this.props.roomId),
|
room: this.props.roomId ? MatrixClientPeg.get().getRoom(this.props.roomId) : null,
|
||||||
messageCap: INITIAL_SIZE
|
messageCap: INITIAL_SIZE
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -50,6 +50,11 @@ module.exports = {
|
||||||
this.focusComposer = false;
|
this.focusComposer = false;
|
||||||
document.addEventListener("keydown", this.onKeyDown);
|
document.addEventListener("keydown", this.onKeyDown);
|
||||||
window.addEventListener("focus", this.onFocus);
|
window.addEventListener("focus", this.onFocus);
|
||||||
|
if (this.state.logged_in) {
|
||||||
|
this.notifyNewScreen('');
|
||||||
|
} else {
|
||||||
|
this.notifyNewScreen('login');
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
|
@ -69,14 +74,45 @@ module.exports = {
|
||||||
|
|
||||||
switch (payload.action) {
|
switch (payload.action) {
|
||||||
case 'logout':
|
case 'logout':
|
||||||
this.setState({
|
this.replaceState({
|
||||||
logged_in: false,
|
logged_in: false,
|
||||||
ready: false
|
ready: false
|
||||||
});
|
});
|
||||||
|
localStorage.removeItem("mx_hs_url");
|
||||||
|
localStorage.removeItem("mx_user_id");
|
||||||
|
localStorage.removeItem("mx_access_token");
|
||||||
Notifier.stop();
|
Notifier.stop();
|
||||||
MatrixClientPeg.get().removeAllListeners();
|
MatrixClientPeg.get().removeAllListeners();
|
||||||
MatrixClientPeg.replace(null);
|
MatrixClientPeg.replace(null);
|
||||||
break;
|
break;
|
||||||
|
case 'start_registration':
|
||||||
|
if (this.state.logged_in) return;
|
||||||
|
var newState = payload.params || {};
|
||||||
|
newState.screen = 'register';
|
||||||
|
if (
|
||||||
|
payload.params &&
|
||||||
|
payload.params.client_secret &&
|
||||||
|
payload.params.session_id &&
|
||||||
|
payload.params.hs_url &&
|
||||||
|
payload.params.is_url &&
|
||||||
|
payload.params.sid
|
||||||
|
) {
|
||||||
|
newState.register_client_secret = payload.params.client_secret;
|
||||||
|
newState.register_session_id = payload.params.session_id;
|
||||||
|
newState.register_hs_url = payload.params.hs_url;
|
||||||
|
newState.register_is_url = payload.params.is_url;
|
||||||
|
newState.register_id_sid = payload.params.sid;
|
||||||
|
}
|
||||||
|
this.replaceState(newState);
|
||||||
|
this.notifyNewScreen('register');
|
||||||
|
break;
|
||||||
|
case 'start_login':
|
||||||
|
if (this.state.logged_in) return;
|
||||||
|
this.replaceState({
|
||||||
|
screen: 'login'
|
||||||
|
});
|
||||||
|
this.notifyNewScreen('login');
|
||||||
|
break;
|
||||||
case 'view_room':
|
case 'view_room':
|
||||||
this.focusComposer = true;
|
this.focusComposer = true;
|
||||||
this.setState({
|
this.setState({
|
||||||
|
@ -111,8 +147,12 @@ module.exports = {
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoggedIn: function() {
|
onLoggedIn: function() {
|
||||||
this.setState({logged_in: true});
|
this.setState({
|
||||||
|
screen: undefined,
|
||||||
|
logged_in: true
|
||||||
|
});
|
||||||
this.startMatrixClient();
|
this.startMatrixClient();
|
||||||
|
this.notifyNewScreen('');
|
||||||
},
|
},
|
||||||
|
|
||||||
startMatrixClient: function() {
|
startMatrixClient: function() {
|
||||||
|
@ -149,5 +189,25 @@ module.exports = {
|
||||||
|
|
||||||
onFocus: function(ev) {
|
onFocus: function(ev) {
|
||||||
dis.dispatch({action: 'focus_composer'});
|
dis.dispatch({action: 'focus_composer'});
|
||||||
|
},
|
||||||
|
|
||||||
|
showScreen(screen, params) {
|
||||||
|
if (screen == 'register') {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'start_registration',
|
||||||
|
params: params
|
||||||
|
});
|
||||||
|
} else if (screen == 'login') {
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'start_login',
|
||||||
|
params: params
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
notifyNewScreen: function(screen) {
|
||||||
|
if (this.props.onNewScreen) {
|
||||||
|
this.props.onNewScreen(screen);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -20,6 +20,7 @@ var React = require('react');
|
||||||
|
|
||||||
var MatrixClientPeg = require("../../MatrixClientPeg");
|
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||||
var Matrix = require("matrix-js-sdk");
|
var Matrix = require("matrix-js-sdk");
|
||||||
|
var dis = require("../../dispatcher");
|
||||||
|
|
||||||
var ComponentBroker = require("../../ComponentBroker");
|
var ComponentBroker = require("../../ComponentBroker");
|
||||||
|
|
||||||
|
@ -41,8 +42,14 @@ module.exports = {
|
||||||
|
|
||||||
onHSChosen: function(ev) {
|
onHSChosen: function(ev) {
|
||||||
ev.preventDefault();
|
ev.preventDefault();
|
||||||
MatrixClientPeg.replaceUsingUrl(this.refs.serverConfig.getHsUrl());
|
MatrixClientPeg.replaceUsingUrls(
|
||||||
this.setState({hs_url: this.refs.serverConfig.getHsUrl()});
|
this.refs.serverConfig.getHsUrl(),
|
||||||
|
this.refs.serverConfig.getIsUrl()
|
||||||
|
);
|
||||||
|
this.setState({
|
||||||
|
hs_url: this.refs.serverConfig.getHsUrl(),
|
||||||
|
is_url: this.refs.serverConfig.getIsUrl()
|
||||||
|
});
|
||||||
this.setStep("fetch_stages");
|
this.setStep("fetch_stages");
|
||||||
var cli = MatrixClientPeg.get();
|
var cli = MatrixClientPeg.get();
|
||||||
this.setState({busy: true});
|
this.setState({busy: true});
|
||||||
|
@ -71,12 +78,14 @@ module.exports = {
|
||||||
// XXX: we assume this means we're logged in, but there could be a next stage
|
// XXX: we assume this means we're logged in, but there could be a next stage
|
||||||
MatrixClientPeg.replace(Matrix.createClient({
|
MatrixClientPeg.replace(Matrix.createClient({
|
||||||
baseUrl: that.state.hs_url,
|
baseUrl: that.state.hs_url,
|
||||||
|
idBaseUrl: that.state.is_url,
|
||||||
userId: data.user_id,
|
userId: data.user_id,
|
||||||
accessToken: data.access_token
|
accessToken: data.access_token
|
||||||
}));
|
}));
|
||||||
var localStorage = window.localStorage;
|
var localStorage = window.localStorage;
|
||||||
if (localStorage) {
|
if (localStorage) {
|
||||||
localStorage.setItem("mx_hs_url", that.state.hs_url);
|
localStorage.setItem("mx_hs_url", that.state.hs_url);
|
||||||
|
localStorage.setItem("mx_is_url", that.state.is_url);
|
||||||
localStorage.setItem("mx_user_id", data.user_id);
|
localStorage.setItem("mx_user_id", data.user_id);
|
||||||
localStorage.setItem("mx_access_token", data.access_token);
|
localStorage.setItem("mx_access_token", data.access_token);
|
||||||
} else {
|
} else {
|
||||||
|
@ -85,9 +94,6 @@ module.exports = {
|
||||||
if (that.props.onLoggedIn) {
|
if (that.props.onLoggedIn) {
|
||||||
that.props.onLoggedIn();
|
that.props.onLoggedIn();
|
||||||
}
|
}
|
||||||
/*dis.dispatch({
|
|
||||||
'action': 'logged_in'
|
|
||||||
});*/
|
|
||||||
}, function(error) {
|
}, function(error) {
|
||||||
that.setStep("stage_m.login.password");
|
that.setStep("stage_m.login.password");
|
||||||
that.setState({errorText: 'Login failed.'});
|
that.setState({errorText: 'Login failed.'});
|
||||||
|
@ -118,4 +124,11 @@ module.exports = {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showRegister: function(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'start_registration'
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
346
src/controllers/templates/Register.js
Normal file
346
src/controllers/templates/Register.js
Normal file
|
@ -0,0 +1,346 @@
|
||||||
|
/*
|
||||||
|
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');
|
||||||
|
|
||||||
|
var MatrixClientPeg = require("../../MatrixClientPeg");
|
||||||
|
var Matrix = require("matrix-js-sdk");
|
||||||
|
var dis = require("../../dispatcher");
|
||||||
|
|
||||||
|
var ComponentBroker = require("../../ComponentBroker");
|
||||||
|
|
||||||
|
var ServerConfig = ComponentBroker.get("molecules/ServerConfig");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getInitialState: function() {
|
||||||
|
return {
|
||||||
|
step: 'initial',
|
||||||
|
busy: false,
|
||||||
|
currentStep: 0,
|
||||||
|
totalSteps: 1
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillMount: function() {
|
||||||
|
this.readNewProps();
|
||||||
|
},
|
||||||
|
|
||||||
|
componentWillReceiveProps: function() {
|
||||||
|
this.readNewProps();
|
||||||
|
},
|
||||||
|
|
||||||
|
readNewProps: function() {
|
||||||
|
if (this.props.clientSecret && this.props.hsUrl &&
|
||||||
|
this.props.isUrl && this.props.sessionId &&
|
||||||
|
this.props.idSid) {
|
||||||
|
this.authSessionId = this.props.sessionId;
|
||||||
|
MatrixClientPeg.replaceUsingUrls(
|
||||||
|
this.props.hsUrl,
|
||||||
|
this.props.isUrl
|
||||||
|
);
|
||||||
|
this.setState({
|
||||||
|
hs_url: this.props.hsUrl,
|
||||||
|
is_url: this.props.isUrl
|
||||||
|
});
|
||||||
|
this.savedParams = {client_secret: this.props.clientSecret};
|
||||||
|
this.setState({busy: true});
|
||||||
|
|
||||||
|
var isLocation = document.createElement('a');
|
||||||
|
isLocation.href = this.props.isUrl;
|
||||||
|
|
||||||
|
var auth = {
|
||||||
|
type: 'm.login.email.identity',
|
||||||
|
threepid_creds: {
|
||||||
|
sid: this.props.idSid,
|
||||||
|
client_secret: this.savedParams.client_secret,
|
||||||
|
id_server: isLocation.host
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this.tryRegister(auth);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
componentDidUpdate: function() {
|
||||||
|
// Just putting a script tag into the returned jsx doesn't work, annoyingly,
|
||||||
|
// so we do this instead.
|
||||||
|
if (this.refs.recaptchaContainer) {
|
||||||
|
var scriptTag = document.createElement('script');
|
||||||
|
window.mx_on_recaptcha_loaded = this.onCaptchaLoaded;
|
||||||
|
scriptTag.setAttribute('src', "https://www.google.com/recaptcha/api.js?onload=mx_on_recaptcha_loaded&render=explicit");
|
||||||
|
this.refs.recaptchaContainer.getDOMNode().appendChild(scriptTag);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setStep: function(step) {
|
||||||
|
this.setState({ step: step, errorText: '', busy: false });
|
||||||
|
},
|
||||||
|
|
||||||
|
getSupportedStageTypes: function() {
|
||||||
|
return ['m.login.email.identity', 'm.login.recaptcha'];
|
||||||
|
},
|
||||||
|
|
||||||
|
chooseFlow: function(flows) {
|
||||||
|
// this is fairly simple right now
|
||||||
|
var supportedTypes = this.getSupportedStageTypes();
|
||||||
|
|
||||||
|
var emailFlow = null;
|
||||||
|
var otherFlow = null;
|
||||||
|
for (var flowI = 0; flowI < flows.length; ++flowI) {
|
||||||
|
var flow = flows[flowI];
|
||||||
|
var flowHasEmail = false;
|
||||||
|
var flowSupported = true;
|
||||||
|
for (var stageI = 0; stageI < flow.stages.length; ++stageI) {
|
||||||
|
var stage = flow.stages[stageI];
|
||||||
|
|
||||||
|
if (supportedTypes.indexOf(stage) == -1) {
|
||||||
|
flowSupported = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stage == 'm.login.email.identity') {
|
||||||
|
flowHasEmail = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (flowSupported) {
|
||||||
|
if (flowHasEmail) {
|
||||||
|
emailFlow = flow;
|
||||||
|
} else {
|
||||||
|
otherFlow = flow;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
this.savedParams.email != '' ||
|
||||||
|
this.completedStages.indexOf('m.login.email.identity' > -1)
|
||||||
|
) {
|
||||||
|
return emailFlow;
|
||||||
|
} else {
|
||||||
|
return otherFlow;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
firstUncompletedStageIndex: function(flow) {
|
||||||
|
if (this.completedStages === undefined) return 0;
|
||||||
|
for (var i = 0; i < flow.stages.length; ++i) {
|
||||||
|
if (this.completedStages.indexOf(flow.stages[i]) == -1) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
numCompletedStages: function(flow) {
|
||||||
|
if (this.completedStages === undefined) return 0;
|
||||||
|
var nCompleted = 0;
|
||||||
|
for (var i = 0; i < flow.stages.length; ++i) {
|
||||||
|
if (this.completedStages.indexOf(flow.stages[i]) > -1) {
|
||||||
|
++nCompleted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nCompleted;
|
||||||
|
},
|
||||||
|
|
||||||
|
onInitialStageSubmit: function(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
MatrixClientPeg.replaceUsingUrls(
|
||||||
|
this.refs.serverConfig.getHsUrl(),
|
||||||
|
this.refs.serverConfig.getIsUrl()
|
||||||
|
);
|
||||||
|
this.setState({
|
||||||
|
hs_url: this.refs.serverConfig.getHsUrl(),
|
||||||
|
is_url: this.refs.serverConfig.getIsUrl()
|
||||||
|
});
|
||||||
|
var cli = MatrixClientPeg.get();
|
||||||
|
this.setState({busy: true});
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
this.savedParams = {
|
||||||
|
email: this.refs.email.getDOMNode().value,
|
||||||
|
username: this.refs.username.getDOMNode().value,
|
||||||
|
password: this.refs.password.getDOMNode().value
|
||||||
|
};
|
||||||
|
|
||||||
|
this.tryRegister();
|
||||||
|
},
|
||||||
|
|
||||||
|
startStage: function(stageName) {
|
||||||
|
var self = this;
|
||||||
|
this.setStep('stage_'+stageName);
|
||||||
|
switch(stageName) {
|
||||||
|
case 'm.login.email.identity':
|
||||||
|
self.setState({
|
||||||
|
busy: true
|
||||||
|
});
|
||||||
|
var cli = MatrixClientPeg.get();
|
||||||
|
this.savedParams.client_secret = cli.generateClientSecret();
|
||||||
|
this.savedParams.send_attempt = 1;
|
||||||
|
|
||||||
|
var nextLink = this.props.registrationUrl +
|
||||||
|
'?client_secret=' +
|
||||||
|
encodeURIComponent(this.savedParams.client_secret) +
|
||||||
|
"&hs_url=" +
|
||||||
|
encodeURIComponent(this.state.hs_url) +
|
||||||
|
"&is_url=" +
|
||||||
|
encodeURIComponent(this.state.is_url) +
|
||||||
|
"&session_id=" +
|
||||||
|
encodeURIComponent(this.authSessionId);
|
||||||
|
|
||||||
|
cli.requestEmailToken(
|
||||||
|
this.savedParams.email,
|
||||||
|
this.savedParams.client_secret,
|
||||||
|
this.savedParams.send_attempt,
|
||||||
|
nextLink
|
||||||
|
).done(function(response) {
|
||||||
|
self.setState({
|
||||||
|
busy: false,
|
||||||
|
});
|
||||||
|
self.setStep('stage_m.login.email.identity');
|
||||||
|
}, function(error) {
|
||||||
|
self.setState({
|
||||||
|
busy: false,
|
||||||
|
errorText: 'Unable to contact the given Home Server'
|
||||||
|
});
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
case 'm.login.recaptcha':
|
||||||
|
if (!this.authParams || !this.authParams['m.login.recaptcha'].public_key) {
|
||||||
|
this.setState({
|
||||||
|
errorText: "This server has not supplied enough information for Recaptcha authentication"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onRegistered: function(user_id, access_token) {
|
||||||
|
MatrixClientPeg.replace(Matrix.createClient({
|
||||||
|
baseUrl: this.state.hs_url,
|
||||||
|
idBaseUrl: this.state.is_url,
|
||||||
|
userId: user_id,
|
||||||
|
accessToken: access_token
|
||||||
|
}));
|
||||||
|
var localStorage = window.localStorage;
|
||||||
|
if (localStorage) {
|
||||||
|
localStorage.setItem("mx_hs_url", this.state.hs_url);
|
||||||
|
localStorage.setItem("mx_user_id", user_id);
|
||||||
|
localStorage.setItem("mx_access_token", access_token);
|
||||||
|
} else {
|
||||||
|
console.warn("No local storage available: can't persist session!");
|
||||||
|
}
|
||||||
|
if (this.props.onLoggedIn) {
|
||||||
|
this.props.onLoggedIn();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
componentForStep: function(step) {
|
||||||
|
switch (step) {
|
||||||
|
case 'initial':
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<form onSubmit={this.onInitialStageSubmit}>
|
||||||
|
Email: <input type="text" ref="email" /><br />
|
||||||
|
Username: <input type="text" ref="username" /><br />
|
||||||
|
Password: <input type="password" ref="password" /><br />
|
||||||
|
<ServerConfig ref="serverConfig" />
|
||||||
|
<input type="submit" value="Continue" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
// XXX: clearly these should be separate organisms
|
||||||
|
case 'stage_m.login.email.identity':
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
Please check your email to continue registration.
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
case 'stage_m.login.recaptcha':
|
||||||
|
return (
|
||||||
|
<div ref="recaptchaContainer">
|
||||||
|
This Home Server would like to make sure you're not a robot
|
||||||
|
<div id="mx_recaptcha"></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onCaptchaLoaded: function() {
|
||||||
|
if (this.refs.recaptchaContainer) {
|
||||||
|
var sitekey = this.authParams['m.login.recaptcha'].public_key;
|
||||||
|
global.grecaptcha.render('mx_recaptcha', {
|
||||||
|
'sitekey': sitekey,
|
||||||
|
'callback': this.onCaptchaDone
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onCaptchaDone: function(captcha_response) {
|
||||||
|
this.tryRegister({
|
||||||
|
type: 'm.login.recaptcha',
|
||||||
|
response: captcha_response
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
tryRegister: function(auth) {
|
||||||
|
var self = this;
|
||||||
|
MatrixClientPeg.get().register(
|
||||||
|
this.savedParams.username,
|
||||||
|
this.savedParams.password,
|
||||||
|
this.authSessionId,
|
||||||
|
auth
|
||||||
|
).done(function(result) {
|
||||||
|
self.onRegistered(result.user_id, result.access_token);
|
||||||
|
}, function(error) {
|
||||||
|
if (error.httpStatus == 401 && error.data.flows) {
|
||||||
|
self.authParams = error.data.params;
|
||||||
|
self.authSessionId = error.data.session;
|
||||||
|
|
||||||
|
self.completedStages = error.data.completed;
|
||||||
|
|
||||||
|
var flow = self.chooseFlow(error.data.flows);
|
||||||
|
|
||||||
|
var flowStage = self.firstUncompletedStageIndex(flow);
|
||||||
|
var numDone = self.numCompletedStages(flow);
|
||||||
|
|
||||||
|
self.setState({
|
||||||
|
busy: false,
|
||||||
|
flows: flow,
|
||||||
|
currentStep: 1+numDone,
|
||||||
|
totalSteps: flow.stages.length+1,
|
||||||
|
flowStage: flowStage
|
||||||
|
});
|
||||||
|
self.startStage(flow.stages[flowStage]);
|
||||||
|
} else {
|
||||||
|
var errorText = "Unable to contact the given Home Server";
|
||||||
|
if (error.httpStatus == 401) {
|
||||||
|
errorText = "Authorisation failed!";
|
||||||
|
}
|
||||||
|
self.setStep("initial");
|
||||||
|
self.setState({
|
||||||
|
busy: false,
|
||||||
|
errorText: errorText
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
showLogin: function(ev) {
|
||||||
|
ev.preventDefault();
|
||||||
|
dis.dispatch({
|
||||||
|
action: 'start_login'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
Loading…
Reference in a new issue