Skip to content

Commit

Permalink
Merge pull request #1002 from matrix-org/jryans/is-v2-auth
Browse files Browse the repository at this point in the history
Add support for IS v2 API with authentication
  • Loading branch information
jryans authored Jul 30, 2019
2 parents 9a8af05 + 50c590a commit 2450d46
Show file tree
Hide file tree
Showing 2 changed files with 135 additions and 23 deletions.
144 changes: 122 additions & 22 deletions src/base-apis.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,16 @@ limitations under the License.
*/
"use strict";

import { SERVICE_TYPES } from './service-types';

/**
* This is an internal module. MatrixBaseApis is currently only meant to be used
* by {@link client~MatrixClient}.
*
* @module base-apis
*/

import { SERVICE_TYPES } from './service-types';
import logger from './logger';

const httpApi = require("./http-api");
const utils = require("./utils");

Expand Down Expand Up @@ -1701,10 +1702,31 @@ MatrixBaseApis.prototype.getKeyChanges = function(oldToken, newToken) {
// Identity Server Operations
// ==========================

/**
* Register with an Identity Server using the OpenID token from the user's
* Homeserver, which can be retrieved via
* {@link module:client~MatrixClient#getOpenIdToken}.
*
* Note that the `/account/register` endpoint (as well as IS authentication in
* general) was added as part of the v2 API version.
*
* @param {object} hsOpenIdToken
* @return {module:client.Promise} Resolves: with object containing an Identity
* Server access token.
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixBaseApis.prototype.registerWithIdentityServer = function(hsOpenIdToken) {
const uri = this.idBaseUrl + httpApi.PREFIX_IDENTITY_V2 + "/account/register";
return this._http.requestOtherUrl(
undefined, "POST", uri,
null, hsOpenIdToken,
);
};

/**
* Requests an email verification token directly from an Identity Server.
*
* Note that the Home Server offers APIs to proxy this API for specific
* Note that the Homeserver offers APIs to proxy this API for specific
* situations, allowing for better feedback to the user.
*
* @param {string} email The email address to request a token for
Expand All @@ -1717,22 +1739,50 @@ MatrixBaseApis.prototype.getKeyChanges = function(oldToken, newToken) {
* @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 ID server is set
* @throws Error if no Identity Server is set
*/
MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret,
sendAttempt, nextLink, callback) {
MatrixBaseApis.prototype.requestEmailToken = async function(
email,
clientSecret,
sendAttempt,
nextLink,
callback,
identityAccessToken,
) {
const 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,
);

try {
const response = await this._http.idServerRequest(
undefined, "POST", "/validate/email/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/email/requestToken",
params, httpApi.PREFIX_IDENTITY_V1,
);
}
if (callback) callback(err);
throw err;
}
};

/**
Expand All @@ -1746,44 +1796,94 @@ MatrixBaseApis.prototype.requestEmailToken = function(email, clientSecret,
* @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.
* @param {string} msisdnToken The MSISDN token, as enetered by the user.
* @param {string} identityAccessToken The `access_token` field of the Identity
* Server `/account/register` response (see {@link registerWithIdentityServer}).
*
* @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) {
MatrixBaseApis.prototype.submitMsisdnToken = async function(
sid,
clientSecret,
msisdnToken,
identityAccessToken,
) {
const params = {
sid: sid,
client_secret: clientSecret,
token: token,
token: msisdnToken,
};
return this._http.idServerRequest(
undefined, "POST", "/validate/msisdn/submitToken",
params, httpApi.PREFIX_IDENTITY_V1,
);

try {
return await this._http.idServerRequest(
undefined, "POST", "/validate/msisdn/submitToken",
params, httpApi.PREFIX_IDENTITY_V2, identityAccessToken,
);
} 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(
undefined, "POST", "/validate/msisdn/submitToken",
params, httpApi.PREFIX_IDENTITY_V1,
);
}
throw err;
}
};

/**
* Looks up the public Matrix ID mapping for a given 3rd party
* identifier from the Identity Server
*
* @param {string} medium The medium of the threepid, eg. 'email'
* @param {string} address The textual address of the threepid
* @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: A threepid mapping
* object or the empty object if no mapping
* exists
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixBaseApis.prototype.lookupThreePid = function(medium, address, callback) {
MatrixBaseApis.prototype.lookupThreePid = async function(
medium,
address,
callback,
identityAccessToken,
) {
const params = {
medium: medium,
address: address,
};
return this._http.idServerRequest(
callback, "GET", "/lookup",
params, httpApi.PREFIX_IDENTITY_V1,
);

try {
const response = await this._http.idServerRequest(
undefined, "GET", "/lookup",
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, "GET", "/lookup",
params, httpApi.PREFIX_IDENTITY_V1,
);
}
if (callback) callback(err);
throw err;
}
};


Expand Down
14 changes: 13 additions & 1 deletion src/http-api.js
Original file line number Diff line number Diff line change
Expand Up @@ -374,7 +374,14 @@ module.exports.MatrixHttpApi.prototype = {
return this.uploads;
},

idServerRequest: function(callback, method, path, params, prefix) {
idServerRequest: function(
callback,
method,
path,
params,
prefix,
accessToken,
) {
const fullUri = this.opts.idBaseUrl + prefix + path;

if (callback !== undefined && !utils.isFunction(callback)) {
Expand All @@ -395,6 +402,11 @@ module.exports.MatrixHttpApi.prototype = {
} else {
opts.form = params;
}
if (accessToken) {
opts.headers = {
Authorization: `Bearer ${accessToken}`,
};
}

const defer = Promise.defer();
this.opts.request(
Expand Down

0 comments on commit 2450d46

Please sign in to comment.