1
0
mirror of https://github.com/matrix-org/matrix-js-sdk.git synced 2025-11-26 17:03:12 +03:00

Merge pull request #1038 from matrix-org/jryans/msc2290

Add separate 3PID add and bind APIs
This commit is contained in:
J. Ryan Stinnett
2019-09-20 14:37:00 +01:00
committed by GitHub
2 changed files with 173 additions and 13 deletions

View File

@@ -1339,10 +1339,16 @@ MatrixBaseApis.prototype.getThreePids = function(callback) {
}; };
/** /**
* Add a 3PID to your homeserver account and optionally bind it to an identity
* server as well. An identity server is required as part of the `creds` object.
*
* This API is deprecated, and you should instead use `addThreePidOnly`
* for homeservers that support it.
*
* @param {Object} creds * @param {Object} creds
* @param {boolean} bind * @param {boolean} bind
* @param {module:client.callback} callback Optional. * @param {module:client.callback} callback Optional.
* @return {module:client.Promise} Resolves: TODO * @return {module:client.Promise} Resolves: on success
* @return {module:http-api.MatrixError} Rejects: with an error response. * @return {module:http-api.MatrixError} Rejects: with an error response.
*/ */
MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) { MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) {
@@ -1356,6 +1362,75 @@ MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) {
); );
}; };
/**
* Add a 3PID to your homeserver account. This API does not use an identity
* server, as the homeserver is expected to handle 3PID ownership validation.
*
* You can check whether a homeserver supports this API via
* `doesServerSupportSeparateAddAndBind`.
*
* @param {Object} data A object with 3PID validation data from having called
* `account/3pid/<medium>/requestToken` on the homeserver.
* @return {module:client.Promise} Resolves: on success
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixBaseApis.prototype.addThreePidOnly = function(data) {
const path = "/account/3pid/add";
return this._http.authedRequest(
undefined, "POST", path, null, data, {
prefix: httpApi.PREFIX_UNSTABLE,
},
);
};
/**
* Bind a 3PID for discovery onto an identity server via the homeserver. The
* identity server handles 3PID ownership validation and the homeserver records
* the new binding to track where all 3PIDs for the account are bound.
*
* You can check whether a homeserver supports this API via
* `doesServerSupportSeparateAddAndBind`.
*
* @param {Object} data A object with 3PID validation data from having called
* `validate/<medium>/requestToken` on the identity server. It should also
* contain `id_server` and `id_access_token` fields as well.
* @return {module:client.Promise} Resolves: on success
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixBaseApis.prototype.bindThreePid = function(data) {
const path = "/account/3pid/bind";
return this._http.authedRequest(
undefined, "POST", path, null, data, {
prefix: httpApi.PREFIX_UNSTABLE,
},
);
};
/**
* Unbind a 3PID for discovery on an identity server via the homeserver. The
* homeserver removes its record of the binding to keep an updated record of
* where all 3PIDs for the account are bound.
*
* @param {string} medium The threepid medium (eg. 'email')
* @param {string} address The threepid address (eg. 'bob@example.com')
* this must be as returned by getThreePids.
* @return {module:client.Promise} Resolves: on success
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixBaseApis.prototype.unbindThreePid = function(medium, address) {
const path = "/account/3pid/unbind";
const data = {
medium,
address,
id_server: this.getIdentityServerUrl(true),
};
return this._http.authedRequest(
undefined, "POST", path, null, data, {
prefix: httpApi.PREFIX_UNSTABLE,
},
);
};
/** /**
* @param {string} medium The threepid medium (eg. 'email') * @param {string} medium The threepid medium (eg. 'email')
* @param {string} address The threepid address (eg. 'bob@example.com') * @param {string} address The threepid address (eg. 'bob@example.com')
@@ -1757,10 +1832,11 @@ MatrixBaseApis.prototype.registerWithIdentityServer = function(hsOpenIdToken) {
}; };
/** /**
* Requests an email verification token directly from an Identity Server. * Requests an email verification token directly from an identity server.
* *
* Note that the Homeserver offers APIs to proxy this API for specific * This API is used as part of binding an email for discovery on an identity
* situations, allowing for better feedback to the user. * server. The validation data that results should be passed to the
* `bindThreePid` method to complete the binding process.
* *
* @param {string} email The email address to request a token for * @param {string} email The email address to request a token for
* @param {string} clientSecret A secret binary string generated by the client. * @param {string} clientSecret A secret binary string generated by the client.
@@ -1772,12 +1848,12 @@ MatrixBaseApis.prototype.registerWithIdentityServer = function(hsOpenIdToken) {
* @param {string} nextLink Optional If specified, the client will be redirected * @param {string} nextLink Optional If specified, the client will be redirected
* to this link after validation. * to this link after validation.
* @param {module:client.callback} callback Optional. * @param {module:client.callback} callback Optional.
* @param {string} identityAccessToken The `access_token` field of the Identity * @param {string} identityAccessToken The `access_token` field of the identity
* Server `/account/register` response (see {@link registerWithIdentityServer}). * server `/account/register` response (see {@link registerWithIdentityServer}).
* *
* @return {module:client.Promise} Resolves: TODO * @return {module:client.Promise} Resolves: TODO
* @return {module:http-api.MatrixError} Rejects: with an error response. * @return {module:http-api.MatrixError} Rejects: with an error response.
* @throws Error if no Identity Server is set * @throws Error if no identity server is set
*/ */
MatrixBaseApis.prototype.requestEmailToken = async function( MatrixBaseApis.prototype.requestEmailToken = async function(
email, email,
@@ -1818,6 +1894,74 @@ MatrixBaseApis.prototype.requestEmailToken = async function(
} }
}; };
/**
* Requests a MSISDN verification token directly from an identity server.
*
* This API is used as part of binding a MSISDN for discovery on an identity
* server. The validation data that results should be passed to the
* `bindThreePid` method to complete the binding process.
*
* @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 A secret binary string generated by the client.
* It is recommended this be around 16 ASCII characters.
* @param {number} sendAttempt If an identity server sees a duplicate request
* with the same sendAttempt, it will not send another SMS.
* To request another SMS to be sent, use a larger value for
* the sendAttempt param as was used in the previous request.
* @param {string} nextLink Optional If specified, the client will be redirected
* to this link after validation.
* @param {module:client.callback} callback Optional.
* @param {string} identityAccessToken The `access_token` field of the Identity
* Server `/account/register` response (see {@link registerWithIdentityServer}).
*
* @return {module:client.Promise} Resolves: TODO
* @return {module:http-api.MatrixError} Rejects: with an error response.
* @throws Error if no identity server is set
*/
MatrixBaseApis.prototype.requestMsisdnToken = async function(
phoneCountry,
phoneNumber,
clientSecret,
sendAttempt,
nextLink,
callback,
identityAccessToken,
) {
const params = {
client_secret: clientSecret,
country: phoneCountry,
phone_number: phoneNumber,
send_attempt: sendAttempt,
next_link: nextLink,
};
try {
const response = await this._http.idServerRequest(
undefined, "POST", "/validate/msisdn/requestToken",
params, httpApi.PREFIX_IDENTITY_V2, identityAccessToken,
);
// TODO: Fold callback into above call once v1 path below is removed
if (callback) callback(null, response);
return response;
} catch (err) {
if (err.cors === "rejected" || err.httpStatus === 404) {
// Fall back to deprecated v1 API for now
// TODO: Remove this path once v2 is only supported version
// See https://github.com/vector-im/riot-web/issues/10443
logger.warn("IS doesn't support v2, falling back to deprecated v1");
return await this._http.idServerRequest(
callback, "POST", "/validate/msisdn/requestToken",
params, httpApi.PREFIX_IDENTITY_V1,
);
}
if (callback) callback(err);
throw err;
}
};
/** /**
* Submits an MSISDN token to the identity server * Submits an MSISDN token to the identity server
* *

View File

@@ -4154,7 +4154,7 @@ MatrixClient.prototype.stopClient = function() {
global.clearTimeout(this._checkTurnServersTimeoutID); global.clearTimeout(this._checkTurnServersTimeoutID);
}; };
/* /**
* Get the API versions supported by the server, along with any * Get the API versions supported by the server, along with any
* unstable APIs it supports * unstable APIs it supports
* @return {Promise<object>} The server /versions response * @return {Promise<object>} The server /versions response
@@ -4174,7 +4174,7 @@ MatrixClient.prototype.getVersions = async function() {
return this._serverVersionsCache; return this._serverVersionsCache;
}; };
/* /**
* Query the server to see if it support members lazy loading * Query the server to see if it support members lazy loading
* @return {Promise<boolean>} true if server supports lazy loading * @return {Promise<boolean>} true if server supports lazy loading
*/ */
@@ -4188,7 +4188,7 @@ MatrixClient.prototype.doesServerSupportLazyLoading = async function() {
|| (unstableFeatures && unstableFeatures["m.lazy_load_members"]); || (unstableFeatures && unstableFeatures["m.lazy_load_members"]);
}; };
/* /**
* Query the server to see if the `id_server` parameter is required * Query the server to see if the `id_server` parameter is required
* when registering with an 3pid, adding a 3pid or resetting password. * when registering with an 3pid, adding a 3pid or resetting password.
* @return {Promise<boolean>} true if id_server parameter is required * @return {Promise<boolean>} true if id_server parameter is required
@@ -4211,7 +4211,7 @@ MatrixClient.prototype.doesServerRequireIdServerParam = async function() {
} }
}; };
/* /**
* Query the server to see if the `id_access_token` parameter can be safely * Query the server to see if the `id_access_token` parameter can be safely
* passed to the homeserver. Some homeservers may trigger errors if they are not * passed to the homeserver. Some homeservers may trigger errors if they are not
* prepared for the new parameter. * prepared for the new parameter.
@@ -4227,7 +4227,23 @@ MatrixClient.prototype.doesServerAcceptIdentityAccessToken = async function() {
|| (unstableFeatures && unstableFeatures["m.id_access_token"]); || (unstableFeatures && unstableFeatures["m.id_access_token"]);
}; };
/* /**
* Query the server to see if it supports separate 3PID add and bind functions.
* This affects the sequence of API calls clients should use for these operations,
* so it's helpful to be able to check for support.
* @return {Promise<boolean>} true if separate functions are supported
*/
MatrixClient.prototype.doesServerSupportSeparateAddAndBind = async function() {
const response = await this.getVersions();
const versions = response["versions"];
const unstableFeatures = response["unstable_features"];
return (versions && versions.includes("r0.6.0"))
|| (unstableFeatures && unstableFeatures["m.separate_add_and_bind"]);
};
/**
* Get if lazy loading members is being used. * Get if lazy loading members is being used.
* @return {boolean} Whether or not members are lazy loaded by this client * @return {boolean} Whether or not members are lazy loaded by this client
*/ */
@@ -4235,7 +4251,7 @@ MatrixClient.prototype.hasLazyLoadMembersEnabled = function() {
return !!this._clientOpts.lazyLoadMembers; return !!this._clientOpts.lazyLoadMembers;
}; };
/* /**
* Set a function which is called when /sync returns a 'limited' response. * Set a function which is called when /sync returns a 'limited' response.
* It is called with a room ID and returns a boolean. It should return 'true' if the SDK * It is called with a room ID and returns a boolean. It should return 'true' if the SDK
* can SAFELY remove events from this room. It may not be safe to remove events if there * can SAFELY remove events from this room. It may not be safe to remove events if there