diff --git a/src/base-apis.js b/src/base-apis.js index f1151cc96..3771e7503 100644 --- a/src/base-apis.js +++ b/src/base-apis.js @@ -125,7 +125,9 @@ MatrixBaseApis.prototype.makeTxnId = function() { * @param {string} password * @param {string} sessionId * @param {Object} auth - * @param {boolean} bindEmail + * @param {Object} bindThreepids Set key 'email' to true to bind any email + * threepid uses during registration in the ID server. Set 'msisdn' to + * true to bind msisdn. * @param {string} guestAccessToken * @param {module:client.callback} callback Optional. * @return {module:client.Promise} Resolves: TODO @@ -133,9 +135,16 @@ MatrixBaseApis.prototype.makeTxnId = function() { */ MatrixBaseApis.prototype.register = function( username, password, - sessionId, auth, bindEmail, guestAccessToken, + sessionId, auth, bindThreepids, guestAccessToken, callback, ) { + // backwards compat + if (bindThreepids === true) { + bindThreepids = {email: true}; + } else if (bindThreepids === null || bindThreepids === undefined) { + bindThreepids = {}; + } + if (auth === undefined || auth === null) { auth = {}; } @@ -152,8 +161,11 @@ MatrixBaseApis.prototype.register = function( if (password !== undefined && password !== null) { params.password = password; } - if (bindEmail !== undefined && bindEmail !== null) { - params.bind_email = bindEmail; + if (bindThreepids.email) { + params.bind_email = true; + } + if (bindThreepids.msisdn) { + params.bind_msisdn = true; } if (guestAccessToken !== undefined && guestAccessToken !== null) { params.guest_access_token = guestAccessToken; @@ -1143,6 +1155,35 @@ MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret, ); }; +/** + * Submits an MSISDN token to the identity server + * + * This is used when submitting the code sent by SMS to a phone number. + * The ID server has an equivalent API for email but the js-sdk does + * not expose this, since email is normally validated by the user clicking + * a link rather than entering a code. + * + * @param {string} sid The sid given in the response to requestToken + * @param {string} clientSecret A secret binary string generated by the client. + * This must be the same value submitted in the requestToken call. + * @param {string} token The token, as enetered by the user. + * + * @return {module:client.Promise} Resolves: Object, currently with no parameters. + * @return {module:http-api.MatrixError} Rejects: with an error response. + * @throws Error if No ID server is set + */ +MatrixBaseApis.prototype.submitMsisdnToken = function(sid, clientSecret, token) { + const params = { + sid: sid, + client_secret: clientSecret, + token: token, + }; + return this._http.idServerRequest( + undefined, "POST", "/validate/msisdn/submitToken", + params, httpApi.PREFIX_IDENTITY_V1, + ); +}; + /** * Looks up the public Matrix ID mapping for a given 3rd party * identifier from the Identity Server diff --git a/src/client.js b/src/client.js index 0f6e2306c..eaafeb90a 100644 --- a/src/client.js +++ b/src/client.js @@ -2084,14 +2084,45 @@ MatrixClient.prototype.setGuestAccess = function(roomId, opts) { * @param {string} clientSecret As requestEmailToken * @param {number} sendAttempt As requestEmailToken * @param {string} nextLink As requestEmailToken - * @param {module:client.callback} callback Optional. As requestEmailToken * @return {module:client.Promise} Resolves: As requestEmailToken */ MatrixClient.prototype.requestRegisterEmailToken = function(email, clientSecret, - sendAttempt, nextLink, callback) { + sendAttempt, nextLink) { return this._requestTokenFromEndpoint( "/register/email/requestToken", - email, clientSecret, sendAttempt, nextLink, callback, + { + email: email, + client_secret: clientSecret, + send_attempt: sendAttempt, + next_link: nextLink, + }, + ); +}; + +/** + * Requests a text message verification token for the purposes of registration. + * This API proxies the Identity Server /validate/msisdn/requestToken API, + * adding registration-specific behaviour, as with requestRegisterEmailToken. + * + * @param {string} phoneCountry The ISO 3166-1 alpha-2 code for the country in which + * phoneNumber should be parsed relative to. + * @param {string} phoneNumber The phone number, in national or international format + * @param {string} clientSecret As requestEmailToken + * @param {number} sendAttempt As requestEmailToken + * @param {string} nextLink As requestEmailToken + * @return {module:client.Promise} Resolves: As requestEmailToken + */ +MatrixClient.prototype.requestRegisterMsisdnToken = function(phoneCountry, phoneNumber, + clientSecret, sendAttempt, nextLink) { + return this._requestTokenFromEndpoint( + "/register/msisdn/requestToken", + { + country: phoneCountry, + phone_number: phoneNumber, + client_secret: clientSecret, + send_attempt: sendAttempt, + next_link: nextLink, + }, ); }; @@ -2112,14 +2143,46 @@ MatrixClient.prototype.requestRegisterEmailToken = function(email, clientSecret, * @param {string} clientSecret As requestEmailToken * @param {number} sendAttempt As requestEmailToken * @param {string} nextLink As requestEmailToken - * @param {module:client.callback} callback Optional. As requestEmailToken * @return {module:client.Promise} Resolves: As requestEmailToken */ MatrixClient.prototype.requestAdd3pidEmailToken = function(email, clientSecret, - sendAttempt, nextLink, callback) { + sendAttempt, nextLink) { return this._requestTokenFromEndpoint( "/account/3pid/email/requestToken", - email, clientSecret, sendAttempt, nextLink, callback, + { + email: email, + client_secret: clientSecret, + send_attempt: sendAttempt, + next_link: nextLink, + }, + ); +}; + +/** + * Requests a text message verification token for the purposes of adding a + * third party identifier to an account. + * This API proxies the Identity Server /validate/email/requestToken API, + * adding specific behaviour for the addition of phone numbers to an + * account, as requestAdd3pidEmailToken. + * + * @param {string} phoneCountry As requestRegisterMsisdnToken + * @param {string} phoneNumber As requestRegisterMsisdnToken + * @param {string} clientSecret As requestEmailToken + * @param {number} sendAttempt As requestEmailToken + * @param {string} nextLink As requestEmailToken + * @return {module:client.Promise} Resolves: As requestEmailToken + */ +MatrixClient.prototype.requestAdd3pidMsisdnToken = function(phoneCountry, phoneNumber, + clientSecret, sendAttempt, nextLink) { + return this._requestTokenFromEndpoint( + "/account/3pid/msisdn/requestToken", + { + country: phoneCountry, + phone_number: phoneNumber, + client_secret: clientSecret, + send_attempt: sendAttempt, + next_link: nextLink, + }, ); }; @@ -2143,10 +2206,42 @@ MatrixClient.prototype.requestAdd3pidEmailToken = function(email, clientSecret, * @return {module:client.Promise} Resolves: As requestEmailToken */ MatrixClient.prototype.requestPasswordEmailToken = function(email, clientSecret, - sendAttempt, nextLink, callback) { + sendAttempt, nextLink) { return this._requestTokenFromEndpoint( "/account/password/email/requestToken", - email, clientSecret, sendAttempt, nextLink, callback, + { + email: email, + client_secret: clientSecret, + send_attempt: sendAttempt, + next_link: nextLink, + }, + ); +}; + +/** + * Requests a text message verification token for the purposes of resetting + * the password on an account. + * This API proxies the Identity Server /validate/email/requestToken API, + * adding specific behaviour for the password resetting, as requestPasswordEmailToken. + * + * @param {string} phoneCountry As requestRegisterMsisdnToken + * @param {string} phoneNumber As requestRegisterMsisdnToken + * @param {string} clientSecret As requestEmailToken + * @param {number} sendAttempt As requestEmailToken + * @param {string} nextLink As requestEmailToken + * @return {module:client.Promise} Resolves: As requestEmailToken + */ +MatrixClient.prototype.requestPasswordMsisdnToken = function(phoneCountry, phoneNumber, + clientSecret, sendAttempt, nextLink) { + return this._requestTokenFromEndpoint( + "/account/password/msisdn/requestToken", + { + country: phoneCountry, + phone_number: phoneNumber, + client_secret: clientSecret, + send_attempt: sendAttempt, + next_link: nextLink, + }, ); }; @@ -2155,31 +2250,21 @@ MatrixClient.prototype.requestPasswordEmailToken = function(email, clientSecret, * requestToken endpoints. * * @param {string} endpoint The endpoint to send the request to - * @param {string} email As requestEmailToken - * @param {string} clientSecret As requestEmailToken - * @param {number} sendAttempt As requestEmailToken - * @param {string} nextLink As requestEmailToken - * @param {module:client.callback} callback Optional. As requestEmailToken + * @param {object} params Parameters for the POST request * @return {module:client.Promise} Resolves: As requestEmailToken */ -MatrixClient.prototype._requestTokenFromEndpoint = function(endpoint, - email, clientSecret, - sendAttempt, nextLink, callback) { +MatrixClient.prototype._requestTokenFromEndpoint = function(endpoint, params) { const id_server_url = url.parse(this.idBaseUrl); if (id_server_url.host === null) { throw new Error("Invalid ID server URL: " + this.idBaseUrl); } - const params = { - client_secret: clientSecret, - email: email, - send_attempt: sendAttempt, - next_link: nextLink, + const postParams = Object.assign({}, params, { id_server: id_server_url.host, - }; + }); return this._http.request( - callback, "POST", endpoint, undefined, - params, + undefined, "POST", endpoint, undefined, + postParams, ); };