Skip to content

Commit

Permalink
Send id_access_token to HS for use in proxied IS requests
Browse files Browse the repository at this point in the history
This passes along the `id_access_token` to the HS, which it will need when
speaking v2 IS APIs to the IS.

Unfortunately, some HSes seem to explode when given this new parameter, so we
only pass it along for the moment if an unstable feature `m.id_access_token` is
also set.

Part of element-hq/element-web#10525
Defined in MSC2140
  • Loading branch information
jryans committed Aug 22, 2019
1 parent 898fa0e commit 31e72ef
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 5 deletions.
9 changes: 9 additions & 0 deletions src/base-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,14 @@ function termsUrlForService(serviceType, baseUrl) {
*
* @param {string} opts.accessToken The access_token for this user.
*
* @param {Function} [opts.getIdentityAccessToken]
* Optional. A callback that returns a Promise<String> of an identity access
* token to supply with identity requests. If the callback is unset, no access
* token will be supplied.
* See also https://github.com/vector-im/riot-web/issues/10615 which seeks to
* replace the previous approach of manual access tokens params with this
* callback throughout the SDK.
*
* @param {Number=} opts.localTimeoutMs Optional. The default maximum amount of
* time to wait before timing out HTTP requests. If not specified, there is no
* timeout.
Expand All @@ -79,6 +87,7 @@ function MatrixBaseApis(opts) {

this.baseUrl = opts.baseUrl;
this.idBaseUrl = opts.idBaseUrl;
this.getIdentityAccessToken = opts.getIdentityAccessToken;

const httpOpts = {
baseUrl: opts.baseUrl,
Expand Down
61 changes: 56 additions & 5 deletions src/client.js
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,14 @@ function keyFromRecoverySession(session, decryptionKey) {
*
* @param {string} opts.userId The user ID for this user.
*
* @param {Function} [opts.getIdentityAccessToken]
* Optional. A callback that returns a Promise<String> of an identity access
* token to supply with identity requests. If the callback is unset, no access
* token will be supplied.
* See also https://github.com/vector-im/riot-web/issues/10615 which seeks to
* replace the previous approach of manual access tokens params with this
* callback throughout the SDK.
*
* @param {Object=} opts.store
* The data store used for sync data from the homeserver. If not specified,
* this client will not store any HTTP responses. The `createClient` helper
Expand Down Expand Up @@ -2438,7 +2446,12 @@ MatrixClient.prototype.inviteByEmail = function(roomId, email, callback) {
* @return {module:client.Promise} Resolves: TODO
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixClient.prototype.inviteByThreePid = function(roomId, medium, address, callback) {
MatrixClient.prototype.inviteByThreePid = async function(
roomId,
medium,
address,
callback,
) {
const path = utils.encodeUri(
"/rooms/$roomId/invite",
{ $roomId: roomId },
Expand All @@ -2451,12 +2464,23 @@ MatrixClient.prototype.inviteByThreePid = function(roomId, medium, address, call
errcode: "ORG.MATRIX.JSSDK_MISSING_PARAM",
}));
}

return this._http.authedRequest(callback, "POST", path, undefined, {
const params = {
id_server: identityServerUrl,
medium: medium,
address: address,
});
};

if (
this.getIdentityAccessToken &&
await this.doesServerAcceptIdentityAccessToken()
) {
const identityAccessToken = await this.getIdentityAccessToken();
if (identityAccessToken) {
params.id_access_token = identityAccessToken;
}
}

return this._http.authedRequest(callback, "POST", path, undefined, params);
};

/**
Expand Down Expand Up @@ -3423,7 +3447,7 @@ MatrixClient.prototype.requestPasswordMsisdnToken = function(phoneCountry, phone
* @param {object} params Parameters for the POST request
* @return {module:client.Promise} Resolves: As requestEmailToken
*/
MatrixClient.prototype._requestTokenFromEndpoint = function(endpoint, params) {
MatrixClient.prototype._requestTokenFromEndpoint = async function(endpoint, params) {
const postParams = Object.assign({}, params);

if (this.idBaseUrl) {
Expand All @@ -3432,6 +3456,16 @@ MatrixClient.prototype._requestTokenFromEndpoint = function(endpoint, params) {
throw new Error("Invalid ID server URL: " + this.idBaseUrl);
}
postParams.id_server = idServerUrl.host;

if (
this.getIdentityAccessToken &&
await this.doesServerAcceptIdentityAccessToken()
) {
const identityAccessToken = await this.getIdentityAccessToken();
if (identityAccessToken) {
postParams.id_access_token = identityAccessToken;
}
}
}

return this._http.request(
Expand Down Expand Up @@ -4092,6 +4126,23 @@ MatrixClient.prototype.doesServerRequireIdServerParam = async function() {
}
};

/*
* 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
* prepared for the new parameter.
* @return {Promise<boolean>} true if id_access_token can be sent
*/
MatrixClient.prototype.doesServerAcceptIdentityAccessToken = async function() {
const response = await this.getVersions();

const unstableFeatures = response["unstable_features"];
if (unstableFeatures["m.id_access_token"] === undefined) {
return false;
}

return unstableFeatures["m.id_access_token"];
};

/*
* Get if lazy loading members is being used.
* @return {boolean} Whether or not members are lazy loaded by this client
Expand Down

0 comments on commit 31e72ef

Please sign in to comment.