From 864fdcb9259f5e0036b36d8a9f1cbce85c10ccf4 Mon Sep 17 00:00:00 2001 From: David Baker Date: Mon, 13 Jul 2015 19:15:10 +0100 Subject: [PATCH 1/8] Support V2 registration --- lib/client.js | 29 ++++++++++++++--------------- lib/http-api.js | 1 + 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/client.js b/lib/client.js index 856ecb3ad..33fd10783 100644 --- a/lib/client.js +++ b/lib/client.js @@ -802,15 +802,6 @@ MatrixClient.prototype.publicRooms = function(callback) { return this._http.request(callback, "GET", "/publicRooms"); }; -/** - * @param {module:client.callback} callback Optional. - * @return {module:client.Promise} Resolves: TODO - * @return {module:http-api.MatrixError} Rejects: with an error response. - */ -MatrixClient.prototype.registerFlows = function(callback) { - return this._http.request(callback, "GET", "/register"); -}; - /** * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO @@ -932,16 +923,24 @@ MatrixClient.prototype.login = function(loginType, data, callback) { }; /** - * @param {string} loginType - * @param {Object} data + * @param {string} username + * @param {string} password + * @param {string} session_id + * @param {Object} auth * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ -MatrixClient.prototype.register = function(loginType, data, callback) { - data.type = loginType; - return this._http.authedRequest( - callback, "POST", "/register", undefined, data +MatrixClient.prototype.register = function(username, password, session_id, auth, callback) { + if (auth === undefined) auth = {}; + auth.session = session_id; + return this._http.requestWithPrefix( + callback, "POST", "/register", undefined, + { + username: username, + password: password, + auth: auth + }, httpApi.PREFIX_V2_ALPHA ); }; diff --git a/lib/http-api.js b/lib/http-api.js index 5c8b7b0d5..3aa553157 100644 --- a/lib/http-api.js +++ b/lib/http-api.js @@ -352,6 +352,7 @@ var requestCallback = function(defer, userDefinedCallback, onlyData) { return function(err, response, body) { if (!err && response.statusCode >= 400) { err = new module.exports.MatrixError(body); + err.httpStatus = response.statusCode; } if (err) { From 58df45814b92a62ac1c249691f5c66c9f0ebd987 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Jul 2015 10:09:08 +0100 Subject: [PATCH 2/8] lint errors --- lib/client.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/client.js b/lib/client.js index 33fd10783..d269e7ea1 100644 --- a/lib/client.js +++ b/lib/client.js @@ -931,8 +931,9 @@ MatrixClient.prototype.login = function(loginType, data, callback) { * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ -MatrixClient.prototype.register = function(username, password, session_id, auth, callback) { - if (auth === undefined) auth = {}; +MatrixClient.prototype.register = function(username, password, + session_id, auth, callback) { + if (auth === undefined) { auth = {}; } auth.session = session_id; return this._http.requestWithPrefix( callback, "POST", "/register", undefined, From 77d3add846ee1f5c67094a3f85b1c36fa4519dbd Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Jul 2015 19:36:44 +0100 Subject: [PATCH 3/8] Talk to the ID server --- lib/client.js | 39 ++++++++++++++++++++++++++++++++++++++- lib/http-api.js | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) diff --git a/lib/client.js b/lib/client.js index d269e7ea1..94b018ef8 100644 --- a/lib/client.js +++ b/lib/client.js @@ -45,7 +45,7 @@ var utils = require("./utils"); function MatrixClient(opts) { utils.checkObjectHasKeys(opts, ["baseUrl", "request"]); utils.checkObjectHasNoAdditionalKeys(opts, - ["baseUrl", "request", "accessToken", "userId", "store", "scheduler"] + ["baseUrl", "idBaseUrl", "request", "accessToken", "userId", "store", "scheduler"] ); this.store = opts.store || new StubStore(); @@ -61,6 +61,7 @@ function MatrixClient(opts) { var httpOpts = { baseUrl: opts.baseUrl, + idBaseUrl: opts.idBaseUrl, accessToken: opts.accessToken, request: opts.request, prefix: httpApi.PREFIX_V1, @@ -1381,6 +1382,42 @@ function _PojoToMatrixEventMapper(plainOldJsObject) { return new MatrixEvent(plainOldJsObject); } +// Identity Server Operations +// ========================== + +/** + * @param {string} client_secret + * @param {string} email + * @param {string} send_attempt + * @param {module:client.callback} callback Optional. + * @return {module:client.Promise} Resolves: TODO + * @return {module:http-api.MatrixError} Rejects: with an error response. + */ +MatrixClient.prototype.requestEmailToken = function(email, client_secret, send_attempt, callback) { + var params = { + client_secret: client_secret, + email: email, + send_attempt: send_attempt + }; + return this._http.idServerRequest( + callback, "POST", "/validate/email/requestToken", params, httpApi.PREFIX_IDENTITY_V1 + ); +}; + +/** + * Generates a random string suitable for use as a client secret + */ +MatrixClient.prototype.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; +}; + /** */ module.exports.MatrixClient = MatrixClient; diff --git a/lib/http-api.js b/lib/http-api.js index 3aa553157..100577d71 100644 --- a/lib/http-api.js +++ b/lib/http-api.js @@ -23,6 +23,11 @@ module.exports.PREFIX_V1 = "/_matrix/client/api/v1"; */ module.exports.PREFIX_V2_ALPHA = "/_matrix/client/v2_alpha"; +/** + * URI path for the identity API + */ +module.exports.PREFIX_IDENTITY_V1 = "/_matrix/identity/api/v1"; + /** * Construct a MatrixHttpApi. * @constructor @@ -216,6 +221,36 @@ module.exports.MatrixHttpApi.prototype = { return defer.promise; }, + idServerRequest: function(callback, method, path, params, prefix) { + var fullUri = this.opts.idBaseUrl + prefix + path; + + if (callback !== undefined && !utils.isFunction(callback)) { + throw Error( + "Expected callback to be a function but got " + typeof callback + ); + } + + var opts = { + uri: fullUri, + method: method, + withCredentials: false, + json: false, + _matrix_opts: this.opts + }; + if (method == 'GET') { + opts.qs = params; + } else { + opts.form = params; + } + + var defer = q.defer(); + this.opts.request( + opts, + requestCallback(defer, callback, this.opts.onlyData) + ); + return defer.promise; + }, + /** * Perform an authorised request to the homeserver. * @param {Function} callback Optional. The callback to invoke on From ae7f9ab871f89900a7139a3812e1ea8b80d3a373 Mon Sep 17 00:00:00 2001 From: David Baker Date: Tue, 14 Jul 2015 19:38:56 +0100 Subject: [PATCH 4/8] lint --- lib/client.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/client.js b/lib/client.js index 94b018ef8..8f36af911 100644 --- a/lib/client.js +++ b/lib/client.js @@ -1386,26 +1386,29 @@ function _PojoToMatrixEventMapper(plainOldJsObject) { // ========================== /** - * @param {string} client_secret * @param {string} email + * @param {string} client_secret * @param {string} send_attempt * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ -MatrixClient.prototype.requestEmailToken = function(email, client_secret, send_attempt, callback) { +MatrixClient.prototype.requestEmailToken = function(email, client_secret, + send_attempt, callback) { var params = { client_secret: client_secret, email: email, send_attempt: send_attempt }; return this._http.idServerRequest( - callback, "POST", "/validate/email/requestToken", params, httpApi.PREFIX_IDENTITY_V1 + callback, "POST", "/validate/email/requestToken", + params, httpApi.PREFIX_IDENTITY_V1 ); }; /** * Generates a random string suitable for use as a client secret + * @return {string} A new client secret */ MatrixClient.prototype.generateClientSecret = function() { var ret = ""; From a89de9754f68037ff1af4499687e38ec5320957d Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 15 Jul 2015 19:25:08 +0100 Subject: [PATCH 5/8] Support registration & next_links --- lib/client.js | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/client.js b/lib/client.js index 8f36af911..3334564a7 100644 --- a/lib/client.js +++ b/lib/client.js @@ -935,14 +935,17 @@ MatrixClient.prototype.login = function(loginType, data, callback) { MatrixClient.prototype.register = function(username, password, session_id, auth, callback) { if (auth === undefined) { auth = {}; } - auth.session = session_id; + if (session_id) auth.session = session_id; + + var params = { + auth: auth + }; + if (username !== undefined) params.username = username; + if (password !== undefined ) params.password = password; + return this._http.requestWithPrefix( callback, "POST", "/register", undefined, - { - username: username, - password: password, - auth: auth - }, httpApi.PREFIX_V2_ALPHA + params, httpApi.PREFIX_V2_ALPHA ); }; @@ -1389,16 +1392,18 @@ function _PojoToMatrixEventMapper(plainOldJsObject) { * @param {string} email * @param {string} client_secret * @param {string} send_attempt + * @param {string} next_link Optional * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixClient.prototype.requestEmailToken = function(email, client_secret, - send_attempt, callback) { + send_attempt, next_link, callback) { var params = { client_secret: client_secret, email: email, - send_attempt: send_attempt + send_attempt: send_attempt, + next_link: next_link }; return this._http.idServerRequest( callback, "POST", "/validate/email/requestToken", From 13f72e1df2bcde0812fa3187bfb3fb7267932394 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 15 Jul 2015 19:26:52 +0100 Subject: [PATCH 6/8] lint --- lib/client.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/client.js b/lib/client.js index 3334564a7..4bd229bf9 100644 --- a/lib/client.js +++ b/lib/client.js @@ -935,13 +935,13 @@ MatrixClient.prototype.login = function(loginType, data, callback) { MatrixClient.prototype.register = function(username, password, session_id, auth, callback) { if (auth === undefined) { auth = {}; } - if (session_id) auth.session = session_id; + if (session_id) { auth.session = session_id; } var params = { auth: auth }; - if (username !== undefined) params.username = username; - if (password !== undefined ) params.password = password; + if (username !== undefined) { params.username = username; } + if (password !== undefined) { params.password = password; } return this._http.requestWithPrefix( callback, "POST", "/register", undefined, From ff1b137750ef30499b8fb9ab15227cb0e05bf875 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 16 Jul 2015 10:18:51 +0100 Subject: [PATCH 7/8] add js doc for httpStatus --- lib/http-api.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/http-api.js b/lib/http-api.js index 100577d71..cb082d6b3 100644 --- a/lib/http-api.js +++ b/lib/http-api.js @@ -414,6 +414,7 @@ var requestCallback = function(defer, userDefinedCallback, onlyData) { * @prop {string} name The Matrix 'errcode' value, e.g. "M_FORBIDDEN". * @prop {string} message The Matrix 'error' value, e.g. "Missing token." * @prop {Object} data The raw Matrix error JSON used to construct this object. + * @prop {integer} httpStatus The numeric HTTP status code given */ module.exports.MatrixError = function MatrixError(errorJson) { this.name = errorJson.errcode || "Unknown error code"; From 7b26a646175bc0701bd94e8ba2e29dd791a4b5c1 Mon Sep 17 00:00:00 2001 From: David Baker Date: Thu, 16 Jul 2015 10:20:31 +0100 Subject: [PATCH 8/8] camels --- lib/client.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/client.js b/lib/client.js index 4bd229bf9..f50271099 100644 --- a/lib/client.js +++ b/lib/client.js @@ -926,16 +926,16 @@ MatrixClient.prototype.login = function(loginType, data, callback) { /** * @param {string} username * @param {string} password - * @param {string} session_id + * @param {string} sessionId * @param {Object} auth * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ MatrixClient.prototype.register = function(username, password, - session_id, auth, callback) { + sessionId, auth, callback) { if (auth === undefined) { auth = {}; } - if (session_id) { auth.session = session_id; } + if (sessionId) { auth.session = sessionId; } var params = { auth: auth @@ -1390,20 +1390,20 @@ function _PojoToMatrixEventMapper(plainOldJsObject) { /** * @param {string} email - * @param {string} client_secret - * @param {string} send_attempt - * @param {string} next_link Optional + * @param {string} clientSecret + * @param {string} sendAttempt + * @param {string} nextLink Optional * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO * @return {module:http-api.MatrixError} Rejects: with an error response. */ -MatrixClient.prototype.requestEmailToken = function(email, client_secret, - send_attempt, next_link, callback) { +MatrixClient.prototype.requestEmailToken = function(email, clientSecret, + sendAttempt, nextLink, callback) { var params = { - client_secret: client_secret, + client_secret: clientSecret, email: email, - send_attempt: send_attempt, - next_link: next_link + send_attempt: sendAttempt, + next_link: nextLink }; return this._http.idServerRequest( callback, "POST", "/validate/email/requestToken",