diff --git a/lib/client.js b/lib/client.js index a25348d1d..b38056974 100644 --- a/lib/client.js +++ b/lib/client.js @@ -46,7 +46,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(); @@ -62,6 +62,7 @@ function MatrixClient(opts) { var httpOpts = { baseUrl: opts.baseUrl, + idBaseUrl: opts.idBaseUrl, accessToken: opts.accessToken, request: opts.request, prefix: httpApi.PREFIX_V1, @@ -860,15 +861,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 @@ -990,16 +982,28 @@ MatrixClient.prototype.login = function(loginType, data, callback) { }; /** - * @param {string} loginType - * @param {Object} data + * @param {string} username + * @param {string} password + * @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(loginType, data, callback) { - data.type = loginType; - return this._http.authedRequest( - callback, "POST", "/register", undefined, data +MatrixClient.prototype.register = function(username, password, + sessionId, auth, callback) { + if (auth === undefined) { auth = {}; } + if (sessionId) { auth.session = sessionId; } + + var params = { + auth: auth + }; + if (username !== undefined) { params.username = username; } + if (password !== undefined) { params.password = password; } + + return this._http.requestWithPrefix( + callback, "POST", "/register", undefined, + params, httpApi.PREFIX_V2_ALPHA ); }; @@ -1594,6 +1598,47 @@ function _PojoToMatrixEventMapper(plainOldJsObject) { return new MatrixEvent(plainOldJsObject); } +// Identity Server Operations +// ========================== + +/** + * @param {string} email + * @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, clientSecret, + sendAttempt, nextLink, callback) { + var params = { + client_secret: clientSecret, + email: email, + send_attempt: sendAttempt, + next_link: nextLink + }; + 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 + * @return {string} A new 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 42db907f3..d1a90d7f2 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 @@ -352,6 +387,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) { @@ -378,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";