diff --git a/webclient/app-controller.js b/webclient/app-controller.js index 42c45f7c3..a77d32a5a 100644 --- a/webclient/app-controller.js +++ b/webclient/app-controller.js @@ -85,7 +85,7 @@ angular.module('MatrixWebClientController', ['matrixService', 'mPresence', 'even $scope.logout(); }); - $scope.updateHeader = function() { + $rootScope.updateHeader = function() { $scope.user_id = matrixService.config().user_id; }; diff --git a/webclient/components/matrix/matrix-service.js b/webclient/components/matrix/matrix-service.js index 2ae55bea9..d399aa3cb 100644 --- a/webclient/components/matrix/matrix-service.js +++ b/webclient/components/matrix/matrix-service.js @@ -84,13 +84,14 @@ angular.module('matrixService', []) prefix: prefixPath, // Register an user - register: function(user_name, password) { + register: function(user_name, password, threepidCreds) { // The REST path spec var path = "/register"; return doRequest("POST", path, undefined, { user_id: user_name, - password: password + password: password, + threepidCreds: threepidCreds }); }, @@ -315,9 +316,9 @@ angular.module('matrixService', []) return doBaseRequest(config.identityServer, "POST", path, {}, data, headers); }, - authEmail: function(clientSecret, tokenId, code) { + authEmail: function(clientSecret, sid, code) { var path = "/_matrix/identity/api/v1/validate/email/submitToken"; - var data = "token="+code+"&sid="+tokenId+"&clientSecret="+clientSecret; + var data = "token="+code+"&sid="+sid+"&clientSecret="+clientSecret; var headers = {}; headers["Content-Type"] = "application/x-www-form-urlencoded"; return doBaseRequest(config.identityServer, "POST", path, {}, data, headers); @@ -330,6 +331,11 @@ angular.module('matrixService', []) headers["Content-Type"] = "application/x-www-form-urlencoded"; return doBaseRequest(config.identityServer, "POST", path, {}, data, headers); }, + + lookup3pid: function(medium, address) { + var path = "/_matrix/identity/api/v1/lookup?medium="+encodeURIComponent(medium)+"&address="+encodeURIComponent(address); + return doBaseRequest(config.identityServer, "GET", path, {}, undefined, {}); + }, uploadContent: function(file) { var path = "/_matrix/content"; diff --git a/webclient/login/login-controller.js b/webclient/login/login-controller.js index 7369a28ef..e367b2f0c 100644 --- a/webclient/login/login-controller.js +++ b/webclient/login/login-controller.js @@ -15,8 +15,8 @@ */ angular.module('LoginController', ['matrixService']) -.controller('LoginController', ['$scope', '$location', 'matrixService', 'eventStreamService', - function($scope, $location, matrixService, eventStreamService) { +.controller('LoginController', ['$scope', '$rootScope', '$location', 'matrixService', 'eventStreamService', + function($scope, $rootScope, $location, matrixService, eventStreamService) { 'use strict'; @@ -48,13 +48,39 @@ angular.module('LoginController', ['matrixService']) $scope.login_type = 'mxid'; // TODO: remember the user's preferred login_type $scope.login = function() { + matrixService.setConfig({ + homeserver: $scope.account.homeserver, + identityServer: $scope.account.identityServer, + }); + switch ($scope.login_type) { + case 'mxid': + $scope.login_with_mxid($scope.account.user_id, $scope.account.password); + break; + case 'email': + matrixService.lookup3pid('email', $scope.account.user_id).then( + function(response) { + if (response.data['address'] == undefined) { + $scope.login_error_msg = "Invalid email address / password"; + } else { + console.log("Got address "+response.data['mxid']+" for email "+$scope.account.user_id); + $scope.login_with_mxid(response.data['mxid'], $scope.account.password); + } + }, + function() { + $scope.login_error_msg = "Couldn't look up email address. Is your identity server set correctly?"; + } + ); + } + }; + + $scope.login_with_mxid = function(mxid, password) { matrixService.setConfig({ homeserver: $scope.account.homeserver, identityServer: $scope.account.identityServer, user_id: $scope.account.user_id }); // try to login - matrixService.login($scope.account.user_id, $scope.account.password).then( + matrixService.login(mxid, password).then( function(response) { if ("access_token" in response.data) { $scope.feedback = "Login successful."; @@ -65,6 +91,7 @@ angular.module('LoginController', ['matrixService']) access_token: response.data.access_token }); matrixService.saveConfig(); + $rootScope.updateHeader(); eventStreamService.resume(); $location.url("home"); } diff --git a/webclient/login/register-controller.js b/webclient/login/register-controller.js index 0ece57502..d70e83c3b 100644 --- a/webclient/login/register-controller.js +++ b/webclient/login/register-controller.js @@ -15,8 +15,8 @@ */ angular.module('RegisterController', ['matrixService']) -.controller('RegisterController', ['$scope', '$location', 'matrixService', 'eventStreamService', - function($scope, $location, matrixService, eventStreamService) { +.controller('RegisterController', ['$scope', '$rootScope', '$location', 'matrixService', 'eventStreamService', + function($scope, $rootScope, $location, matrixService, eventStreamService) { 'use strict'; // FIXME: factor out duplication with login-controller.js @@ -30,6 +30,17 @@ angular.module('RegisterController', ['matrixService']) { hs_url += ":" + $location.port(); } + + var generateClientSecret = function() { + var ret = ""; + var chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"; + + for (var i = 0; i < 32; i++) { + ret += chars.charAt(Math.floor(Math.random() * chars.length)); + } + + return ret; + }; $scope.account = { homeserver: hs_url, @@ -43,7 +54,6 @@ angular.module('RegisterController', ['matrixService']) }; $scope.register = function() { - // Set the urls matrixService.setConfig({ homeserver: $scope.account.homeserver, @@ -59,7 +69,25 @@ angular.module('RegisterController', ['matrixService']) return; } - matrixService.register($scope.account.desired_user_id, $scope.account.pwd1).then( + if ($scope.account.email) { + $scope.clientSecret = generateClientSecret(); + matrixService.linkEmail($scope.account.email, $scope.clientSecret, 1).then( + function(response) { + $scope.wait_3pid_code = true; + $scope.sid = response.data.sid; + $scope.feedback = ""; + }, + function(response) { + $scope.feedback = "Couldn't request verification email!"; + } + ); + } else { + registerWithMxidAndPassword($scope.account.desired_user_id, $scope.account.pwd1); + } + }; + + $scope.registerWithMxidAndPassword = function(mxid, password, threepidCreds) { + matrixService.register(mxid, password, threepidCreds).then( function(response) { $scope.feedback = "Success"; // Update the current config @@ -74,7 +102,7 @@ angular.module('RegisterController', ['matrixService']) matrixService.saveConfig(); // Update the global scoped used_id var (used in the app header) - $scope.updateHeader(); + $rootScope.updateHeader(); eventStreamService.resume(); @@ -87,15 +115,32 @@ angular.module('RegisterController', ['matrixService']) $location.url("home"); }, function(error) { + console.trace("Registration error: "+error); if (error.data) { if (error.data.errcode === "M_USER_IN_USE") { $scope.feedback = "Username already taken."; + $scope.reenter_username = true; } } else if (error.status === 0) { $scope.feedback = "Unable to talk to the server."; } }); + } + + $scope.verifyToken = function() { + matrixService.authEmail($scope.clientSecret, $scope.sid, $scope.account.threepidtoken).then( + function(response) { + if (!response.data.success) { + $scope.feedback = "Unable to verify code."; + } else { + $scope.registerWithMxidAndPassword($scope.account.desired_user_id, $scope.account.pwd1, [{'sid':$scope.sid, 'clientSecret':$scope.clientSecret, 'idServer': $scope.account.identityServer.split('//')[1]}]); + } + }, + function(error) { + $scope.feedback = "Unable to verify code."; + } + ); }; }]); diff --git a/webclient/login/register.html b/webclient/login/register.html index 81995f1ae..06a6526b7 100644 --- a/webclient/login/register.html +++ b/webclient/login/register.html @@ -12,26 +12,34 @@

- - - -
- -
- -
- -
-
+ + +
Specifying an email address lets other users find you on Matrix more easily,
+ and will give you a way to reset your password in the future
+ Choose another username: + +
+ +
+ +
+ +
+
- + + +
+ Please enter the verification code sent to {{ account.email }}
+
+ +


{{ feedback }} {{ login_error_msg }}
-
+
Your home server stores all your conversation and account data.