diff --git a/src/ReEmitter.js b/src/ReEmitter.js index 4ddf3229a..84a856bb2 100644 --- a/src/ReEmitter.js +++ b/src/ReEmitter.js @@ -20,7 +20,7 @@ limitations under the License. * @module */ -export default class Reemitter { +export class ReEmitter { constructor(target) { this.target = target; diff --git a/src/autodiscovery.js b/src/autodiscovery.js index 2258eabf4..fe689fd14 100644 --- a/src/autodiscovery.js +++ b/src/autodiscovery.js @@ -17,8 +17,8 @@ limitations under the License. /** @module auto-discovery */ -import logger from './logger'; -import { URL as NodeURL } from "url"; +import {logger} from './logger'; +import {URL as NodeURL} from "url"; // Dev note: Auto discovery is part of the spec. // See: https://matrix.org/docs/spec/client_server/r0.4.0.html#server-discovery diff --git a/src/base-apis.js b/src/base-apis.js index 645ba6e23..8fc4b4048 100644 --- a/src/base-apis.js +++ b/src/base-apis.js @@ -25,17 +25,16 @@ limitations under the License. * @module base-apis */ -import { SERVICE_TYPES } from './service-types'; -import logger from './logger'; - -const httpApi = require("./http-api"); -const utils = require("./utils"); -const PushProcessor = require("./pushprocessor"); +import {SERVICE_TYPES} from './service-types'; +import {logger} from './logger'; +import {PushProcessor} from "./pushprocessor"; +import * as utils from "./utils"; +import {MatrixHttpApi, PREFIX_IDENTITY_V1, PREFIX_IDENTITY_V2, PREFIX_R0, PREFIX_UNSTABLE} from "./http-api"; function termsUrlForService(serviceType, baseUrl) { switch (serviceType) { case SERVICE_TYPES.IS: - return baseUrl + httpApi.PREFIX_IDENTITY_V2 + '/terms'; + return baseUrl + PREFIX_IDENTITY_V2 + '/terms'; case SERVICE_TYPES.IM: return baseUrl + '/_matrix/integrations/v1/terms'; default: @@ -83,7 +82,7 @@ function termsUrlForService(serviceType, baseUrl) { * @param {boolean} [opts.useAuthorizationHeader = false] Set to true to use * Authorization header instead of query param to send the access token to the server. */ -function MatrixBaseApis(opts) { +export function MatrixBaseApis(opts) { utils.checkObjectHasKeys(opts, ["baseUrl", "request"]); this.baseUrl = opts.baseUrl; @@ -95,13 +94,13 @@ function MatrixBaseApis(opts) { idBaseUrl: opts.idBaseUrl, accessToken: opts.accessToken, request: opts.request, - prefix: httpApi.PREFIX_R0, + prefix: PREFIX_R0, onlyData: true, extraParams: opts.queryParams, localTimeoutMs: opts.localTimeoutMs, useAuthorizationHeader: opts.useAuthorizationHeader, }; - this._http = new httpApi.MatrixHttpApi(this, httpOpts); + this._http = new MatrixHttpApi(this, httpOpts); this._txnCtr = 0; } @@ -369,7 +368,7 @@ MatrixBaseApis.prototype.getSsoLoginUrl = function(redirectUrl, loginType) { } return this._http.getUrl("/login/"+loginType+"/redirect", { "redirectUrl": redirectUrl, - }, httpApi.PREFIX_R0); + }, PREFIX_R0); }; /** @@ -447,7 +446,7 @@ MatrixBaseApis.prototype.getFallbackAuthUrl = function(loginType, authSessionId) return this._http.getUrl(path, { session: authSessionId, - }, httpApi.PREFIX_R0); + }, PREFIX_R0); }; // Room operations @@ -499,7 +498,7 @@ MatrixBaseApis.prototype.fetchRelations = }); const response = await this._http.authedRequest( undefined, "GET", path, null, null, { - prefix: httpApi.PREFIX_UNSTABLE, + prefix: PREFIX_UNSTABLE, }, ); return response; @@ -1377,7 +1376,7 @@ MatrixBaseApis.prototype.addThreePid = function(creds, bind, callback) { MatrixBaseApis.prototype.addThreePidOnly = async function(data) { const path = "/account/3pid/add"; const prefix = await this.isVersionSupported("r0.6.0") ? - httpApi.PREFIX_R0 : httpApi.PREFIX_UNSTABLE; + PREFIX_R0 : PREFIX_UNSTABLE; return this._http.authedRequest( undefined, "POST", path, null, data, { prefix }, ); @@ -1400,7 +1399,7 @@ MatrixBaseApis.prototype.addThreePidOnly = async function(data) { MatrixBaseApis.prototype.bindThreePid = async function(data) { const path = "/account/3pid/bind"; const prefix = await this.isVersionSupported("r0.6.0") ? - httpApi.PREFIX_R0 : httpApi.PREFIX_UNSTABLE; + PREFIX_R0 : PREFIX_UNSTABLE; return this._http.authedRequest( undefined, "POST", path, null, data, { prefix }, ); @@ -1425,7 +1424,7 @@ MatrixBaseApis.prototype.unbindThreePid = async function(medium, address) { id_server: this.getIdentityServerUrl(true), }; const prefix = await this.isVersionSupported("r0.6.0") ? - httpApi.PREFIX_R0 : httpApi.PREFIX_UNSTABLE; + PREFIX_R0 : PREFIX_UNSTABLE; return this._http.authedRequest( undefined, "POST", path, null, data, { prefix }, ); @@ -1722,7 +1721,7 @@ MatrixBaseApis.prototype.uploadKeySignatures = function(content) { return this._http.authedRequest( undefined, "POST", '/keys/signatures/upload', undefined, content, { - prefix: httpApi.PREFIX_UNSTABLE, + prefix: PREFIX_UNSTABLE, }, ); }; @@ -1815,7 +1814,7 @@ MatrixBaseApis.prototype.uploadDeviceSigningKeys = function(auth, keys) { const data = Object.assign({}, keys, {auth}); return this._http.authedRequest( undefined, "POST", "/keys/device_signing/upload", undefined, data, { - prefix: httpApi.PREFIX_UNSTABLE, + prefix: PREFIX_UNSTABLE, }, ); }; @@ -1841,7 +1840,7 @@ MatrixBaseApis.prototype.registerWithIdentityServer = function(hsOpenIdToken) { throw new Error("No Identity Server base URL set"); } - const uri = this.idBaseUrl + httpApi.PREFIX_IDENTITY_V2 + "/account/register"; + const uri = this.idBaseUrl + PREFIX_IDENTITY_V2 + "/account/register"; return this._http.requestOtherUrl( undefined, "POST", uri, null, hsOpenIdToken, @@ -1890,7 +1889,7 @@ MatrixBaseApis.prototype.requestEmailToken = async function( try { const response = await this._http.idServerRequest( undefined, "POST", "/validate/email/requestToken", - params, httpApi.PREFIX_IDENTITY_V2, identityAccessToken, + params, PREFIX_IDENTITY_V2, identityAccessToken, ); // TODO: Fold callback into above call once v1 path below is removed if (callback) callback(null, response); @@ -1903,7 +1902,7 @@ MatrixBaseApis.prototype.requestEmailToken = async function( 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, + params, PREFIX_IDENTITY_V1, ); } if (callback) callback(err); @@ -1958,7 +1957,7 @@ MatrixBaseApis.prototype.requestMsisdnToken = async function( try { const response = await this._http.idServerRequest( undefined, "POST", "/validate/msisdn/requestToken", - params, httpApi.PREFIX_IDENTITY_V2, identityAccessToken, + params, PREFIX_IDENTITY_V2, identityAccessToken, ); // TODO: Fold callback into above call once v1 path below is removed if (callback) callback(null, response); @@ -1971,7 +1970,7 @@ MatrixBaseApis.prototype.requestMsisdnToken = async function( 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, + params, PREFIX_IDENTITY_V1, ); } if (callback) callback(err); @@ -2013,7 +2012,7 @@ MatrixBaseApis.prototype.submitMsisdnToken = async function( try { return await this._http.idServerRequest( undefined, "POST", "/validate/msisdn/submitToken", - params, httpApi.PREFIX_IDENTITY_V2, identityAccessToken, + params, PREFIX_IDENTITY_V2, identityAccessToken, ); } catch (err) { if (err.cors === "rejected" || err.httpStatus === 404) { @@ -2023,7 +2022,7 @@ MatrixBaseApis.prototype.submitMsisdnToken = async function( 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, + params, PREFIX_IDENTITY_V1, ); } throw err; @@ -2074,7 +2073,7 @@ MatrixBaseApis.prototype.submitMsisdnTokenOtherUrl = function( MatrixBaseApis.prototype.getIdentityHashDetails = function(identityAccessToken) { return this._http.idServerRequest( undefined, "GET", "/hash_details", - null, httpApi.PREFIX_IDENTITY_V2, identityAccessToken, + null, PREFIX_IDENTITY_V2, identityAccessToken, ); }; @@ -2143,7 +2142,7 @@ MatrixBaseApis.prototype.identityHashedLookup = async function( const response = await this._http.idServerRequest( undefined, "POST", "/lookup", - params, httpApi.PREFIX_IDENTITY_V2, identityAccessToken, + params, PREFIX_IDENTITY_V2, identityAccessToken, ); if (!response || !response['mappings']) return []; // no results @@ -2223,7 +2222,7 @@ MatrixBaseApis.prototype.lookupThreePid = async function( 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, + params, PREFIX_IDENTITY_V1, ); } if (callback) callback(err, undefined); @@ -2281,7 +2280,7 @@ MatrixBaseApis.prototype.bulkLookupThreePids = async function( logger.warn("IS doesn't support v2, falling back to deprecated v1"); return await this._http.idServerRequest( undefined, "POST", "/bulk_lookup", params, - httpApi.PREFIX_IDENTITY_V1, identityAccessToken, + PREFIX_IDENTITY_V1, identityAccessToken, ); } throw err; @@ -2304,7 +2303,7 @@ MatrixBaseApis.prototype.getIdentityAccount = function( ) { return this._http.idServerRequest( undefined, "GET", "/account", - undefined, httpApi.PREFIX_IDENTITY_V2, identityAccessToken, + undefined, PREFIX_IDENTITY_V2, identityAccessToken, ); }; @@ -2432,7 +2431,3 @@ MatrixBaseApis.prototype.reportEvent = function(roomId, eventId, score, reason) return this._http.authedRequest(undefined, "POST", path, null, {score, reason}); }; -/** - * MatrixBaseApis object - */ -module.exports = MatrixBaseApis; diff --git a/src/client.js b/src/client.js index 6f0b4b374..8fa8c7091 100644 --- a/src/client.js +++ b/src/client.js @@ -18,44 +18,39 @@ limitations under the License. */ "use strict"; -const PushProcessor = require('./pushprocessor'); -import {sleep} from './utils'; /** * This is an internal module. See {@link MatrixClient} for the public class. * @module client */ -const EventEmitter = require("events").EventEmitter; -const url = require('url'); -const httpApi = require("./http-api"); -const MatrixEvent = require("./models/event").MatrixEvent; -const EventStatus = require("./models/event").EventStatus; -const EventTimeline = require("./models/event-timeline"); -const SearchResult = require("./models/search-result"); -const StubStore = require("./store/stub"); -const webRtcCall = require("./webrtc/call"); -const utils = require("./utils"); -const contentRepo = require("./content-repo"); -const Filter = require("./filter"); -const SyncApi = require("./sync"); -const MatrixBaseApis = require("./base-apis"); -const MatrixError = httpApi.MatrixError; -const ContentHelpers = require("./content-helpers"); -const olmlib = require("./crypto/olmlib"); - -import ReEmitter from './ReEmitter'; -import RoomList from './crypto/RoomList'; -import logger from './logger'; - -import Crypto from './crypto'; -import { isCryptoAvailable } from './crypto'; -import { decodeRecoveryKey } from './crypto/recoverykey'; -import { keyFromAuthData } from './crypto/key_passphrase'; -import { randomString } from './randomstring'; +import url from "url"; +import {EventEmitter} from "events"; +import {MatrixBaseApis} from "./base-apis"; +import {Filter} from "./filter"; +import {SyncApi} from "./sync"; +import {EventStatus, MatrixEvent} from "./models/event"; +import {EventTimeline} from "./models/event-timeline"; +import {SearchResult} from "./models/search-result"; +import {StubStore} from "./store/stub"; +import {createNewMatrixCall} from "./webrtc/call"; +import * as utils from './utils'; +import {sleep} from './utils'; +import {MatrixError, PREFIX_MEDIA_R0, PREFIX_UNSTABLE} from "./http-api"; +import * as contentRepo from "./content-repo"; +import * as ContentHelpers from "./content-helpers"; +import * as olmlib from "./crypto/olmlib"; +import {ReEmitter} from './ReEmitter'; +import {RoomList} from './crypto/RoomList'; +import {logger} from './logger'; +import {Crypto, isCryptoAvailable} from './crypto'; +import {decodeRecoveryKey} from './crypto/recoverykey'; +import {keyFromAuthData} from './crypto/key_passphrase'; +import {randomString} from './randomstring'; +import {PushProcessor} from "./pushprocessor"; const SCROLLBACK_DELAY_MS = 3000; -const CRYPTO_ENABLED = isCryptoAvailable(); +export const CRYPTO_ENABLED = isCryptoAvailable(); const CAPABILITIES_CACHE_MS = 21600000; // 6 hours - an arbitrary value function keysFromRecoverySession(sessions, decryptionKey, roomId) { @@ -234,7 +229,7 @@ function keyFromRecoverySession(session, decryptionKey) { * {DeviceTrustLevel} device_trust: The trust status of the device requesting * the secret as returned by {@link module:client~MatrixClient#checkDeviceTrust}. */ -function MatrixClient(opts) { +export function MatrixClient(opts) { opts.baseUrl = utils.ensureNoTrailingSlash(opts.baseUrl); opts.idBaseUrl = utils.ensureNoTrailingSlash(opts.idBaseUrl); @@ -273,7 +268,7 @@ function MatrixClient(opts) { // try constructing a MatrixCall to see if we are running in an environment // which has WebRTC. If we are, listen for and handle m.call.* events. - const call = webRtcCall.createNewMatrixCall(this); + const call = createNewMatrixCall(this); this._supportsVoip = false; if (call) { setupCallEventHandler(this); @@ -1345,7 +1340,7 @@ MatrixClient.prototype.checkKeyBackup = function() { MatrixClient.prototype.getKeyBackupVersion = function() { return this._http.authedRequest( undefined, "GET", "/room_keys/version", undefined, undefined, - {prefix: httpApi.PREFIX_UNSTABLE}, + {prefix: PREFIX_UNSTABLE}, ).then((res) => { if (res.algorithm !== olmlib.MEGOLM_BACKUP_ALGORITHM) { const err = "Unknown backup algorithm: " + res.algorithm; @@ -1506,7 +1501,7 @@ MatrixClient.prototype.createKeyBackupVersion = async function(info) { const res = await this._http.authedRequest( undefined, "POST", "/room_keys/version", undefined, data, - {prefix: httpApi.PREFIX_UNSTABLE}, + {prefix: PREFIX_UNSTABLE}, ); this.enableKeyBackup({ algorithm: info.algorithm, @@ -1534,7 +1529,7 @@ MatrixClient.prototype.deleteKeyBackupVersion = function(version) { return this._http.authedRequest( undefined, "DELETE", path, undefined, undefined, - {prefix: httpApi.PREFIX_UNSTABLE}, + {prefix: PREFIX_UNSTABLE}, ); }; @@ -1576,7 +1571,7 @@ MatrixClient.prototype.sendKeyBackup = function(roomId, sessionId, version, data const path = this._makeKeyBackupPath(roomId, sessionId, version); return this._http.authedRequest( undefined, "PUT", path.path, path.queryData, data, - {prefix: httpApi.PREFIX_UNSTABLE}, + {prefix: PREFIX_UNSTABLE}, ); }; @@ -1665,7 +1660,7 @@ MatrixClient.prototype._restoreKeyBackup = function( return this._http.authedRequest( undefined, "GET", path.path, path.queryData, undefined, - {prefix: httpApi.PREFIX_UNSTABLE}, + {prefix: PREFIX_UNSTABLE}, ).then((res) => { if (res.rooms) { for (const [roomId, roomData] of Object.entries(res.rooms)) { @@ -1673,7 +1668,7 @@ MatrixClient.prototype._restoreKeyBackup = function( totalKeyCount += Object.keys(roomData.sessions).length; const roomKeys = keysFromRecoverySession( - roomData.sessions, decryption, roomId, roomKeys, + roomData.sessions, decryption, roomId, ); for (const k of roomKeys) { k.room_id = roomId; @@ -1715,7 +1710,7 @@ MatrixClient.prototype.deleteKeysFromBackup = function(roomId, sessionId, versio const path = this._makeKeyBackupPath(roomId, sessionId, version); return this._http.authedRequest( undefined, "DELETE", path.path, path.queryData, undefined, - {prefix: httpApi.PREFIX_UNSTABLE}, + {prefix: PREFIX_UNSTABLE}, ); }; @@ -1751,7 +1746,7 @@ MatrixClient.prototype.getGroups = function() { MatrixClient.prototype.getMediaConfig = function(callback) { return this._http.authedRequest( callback, "GET", "/config", undefined, undefined, { - prefix: httpApi.PREFIX_MEDIA_R0, + prefix: PREFIX_MEDIA_R0, }, ); }; @@ -2688,7 +2683,7 @@ MatrixClient.prototype.getUrlPreview = function(url, ts, callback) { url: url, ts: ts, }, undefined, { - prefix: httpApi.PREFIX_MEDIA_R0, + prefix: PREFIX_MEDIA_R0, }, ).then(function(response) { // TODO: expire cache occasionally @@ -4797,7 +4792,7 @@ function setupCallEventHandler(client) { ); } - call = webRtcCall.createNewMatrixCall(client, event.getRoomId(), { + call = createNewMatrixCall(client, event.getRoomId(), { forceTURN: client._forceTURN, }); if (!call) { @@ -4897,7 +4892,7 @@ function setupCallEventHandler(client) { // if not live, store the fact that the call has ended because // we're probably getting events backwards so // the hangup will come before the invite - call = webRtcCall.createNewMatrixCall(client, event.getRoomId()); + call = createNewMatrixCall(client, event.getRoomId()); if (call) { call.callId = content.call_id; call._initWithHangup(event); @@ -4997,11 +4992,6 @@ MatrixClient.prototype.generateClientSecret = function() { return randomString(32); }; -/** */ -module.exports.MatrixClient = MatrixClient; -/** */ -module.exports.CRYPTO_ENABLED = CRYPTO_ENABLED; - // MatrixClient Event JSDocs /** diff --git a/src/content-helpers.js b/src/content-helpers.js index a1afe1f71..1d704f05b 100644 --- a/src/content-helpers.js +++ b/src/content-helpers.js @@ -1,5 +1,6 @@ /* Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,85 +17,84 @@ limitations under the License. "use strict"; /** @module ContentHelpers */ -module.exports = { - /** - * Generates the content for a HTML Message event - * @param {string} body the plaintext body of the message - * @param {string} htmlBody the HTML representation of the message - * @returns {{msgtype: string, format: string, body: string, formatted_body: string}} - */ - makeHtmlMessage: function(body, htmlBody) { - return { - msgtype: "m.text", - format: "org.matrix.custom.html", - body: body, - formatted_body: htmlBody, - }; - }, - /** - * Generates the content for a HTML Notice event - * @param {string} body the plaintext body of the notice - * @param {string} htmlBody the HTML representation of the notice - * @returns {{msgtype: string, format: string, body: string, formatted_body: string}} - */ - makeHtmlNotice: function(body, htmlBody) { - return { - msgtype: "m.notice", - format: "org.matrix.custom.html", - body: body, - formatted_body: htmlBody, - }; - }, +/** + * Generates the content for a HTML Message event + * @param {string} body the plaintext body of the message + * @param {string} htmlBody the HTML representation of the message + * @returns {{msgtype: string, format: string, body: string, formatted_body: string}} + */ +export function makeHtmlMessage(body, htmlBody) { + return { + msgtype: "m.text", + format: "org.matrix.custom.html", + body: body, + formatted_body: htmlBody, + }; +} - /** - * Generates the content for a HTML Emote event - * @param {string} body the plaintext body of the emote - * @param {string} htmlBody the HTML representation of the emote - * @returns {{msgtype: string, format: string, body: string, formatted_body: string}} - */ - makeHtmlEmote: function(body, htmlBody) { - return { - msgtype: "m.emote", - format: "org.matrix.custom.html", - body: body, - formatted_body: htmlBody, - }; - }, +/** + * Generates the content for a HTML Notice event + * @param {string} body the plaintext body of the notice + * @param {string} htmlBody the HTML representation of the notice + * @returns {{msgtype: string, format: string, body: string, formatted_body: string}} + */ +export function makeHtmlNotice(body, htmlBody) { + return { + msgtype: "m.notice", + format: "org.matrix.custom.html", + body: body, + formatted_body: htmlBody, + }; +} - /** - * Generates the content for a Plaintext Message event - * @param {string} body the plaintext body of the emote - * @returns {{msgtype: string, body: string}} - */ - makeTextMessage: function(body) { - return { - msgtype: "m.text", - body: body, - }; - }, +/** + * Generates the content for a HTML Emote event + * @param {string} body the plaintext body of the emote + * @param {string} htmlBody the HTML representation of the emote + * @returns {{msgtype: string, format: string, body: string, formatted_body: string}} + */ +export function makeHtmlEmote(body, htmlBody) { + return { + msgtype: "m.emote", + format: "org.matrix.custom.html", + body: body, + formatted_body: htmlBody, + }; +} - /** - * Generates the content for a Plaintext Notice event - * @param {string} body the plaintext body of the notice - * @returns {{msgtype: string, body: string}} - */ - makeNotice: function(body) { - return { - msgtype: "m.notice", - body: body, - }; - }, +/** + * Generates the content for a Plaintext Message event + * @param {string} body the plaintext body of the emote + * @returns {{msgtype: string, body: string}} + */ +export function makeTextMessage(body) { + return { + msgtype: "m.text", + body: body, + }; +} - /** - * Generates the content for a Plaintext Emote event - * @param {string} body the plaintext body of the emote - * @returns {{msgtype: string, body: string}} - */ - makeEmoteMessage: function(body) { - return { - msgtype: "m.emote", - body: body, - }; - }, -}; +/** + * Generates the content for a Plaintext Notice event + * @param {string} body the plaintext body of the notice + * @returns {{msgtype: string, body: string}} + */ +export function makeNotice(body) { + return { + msgtype: "m.notice", + body: body, + }; +} + +/** + * Generates the content for a Plaintext Emote event + * @param {string} body the plaintext body of the emote + * @returns {{msgtype: string, body: string}} + */ +export function makeEmoteMessage(body) { + return { + msgtype: "m.emote", + body: body, + }; +} diff --git a/src/content-repo.js b/src/content-repo.js index 9c0a3306b..4bc4ca688 100644 --- a/src/content-repo.js +++ b/src/content-repo.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -16,95 +17,93 @@ limitations under the License. /** * @module content-repo */ -const utils = require("./utils"); -/** Content Repo utility functions */ -module.exports = { - /** - * Get the HTTP URL for an MXC URI. - * @param {string} baseUrl The base homeserver url which has a content repo. - * @param {string} mxc The mxc:// URI. - * @param {Number} width The desired width of the thumbnail. - * @param {Number} height The desired height of the thumbnail. - * @param {string} resizeMethod The thumbnail resize method to use, either - * "crop" or "scale". - * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs - * directly. Fetching such URLs will leak information about the user to - * anyone they share a room with. If false, will return the emptry string - * for such URLs. - * @return {string} The complete URL to the content. - */ - getHttpUriForMxc: function(baseUrl, mxc, width, height, - resizeMethod, allowDirectLinks) { - if (typeof mxc !== "string" || !mxc) { +import * as utils from "./utils"; + +/** + * Get the HTTP URL for an MXC URI. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} mxc The mxc:// URI. + * @param {Number} width The desired width of the thumbnail. + * @param {Number} height The desired height of the thumbnail. + * @param {string} resizeMethod The thumbnail resize method to use, either + * "crop" or "scale". + * @param {Boolean} allowDirectLinks If true, return any non-mxc URLs + * directly. Fetching such URLs will leak information about the user to + * anyone they share a room with. If false, will return the emptry string + * for such URLs. + * @return {string} The complete URL to the content. + */ +export function getHttpUriForMxc(baseUrl, mxc, width, height, + resizeMethod, allowDirectLinks) { + if (typeof mxc !== "string" || !mxc) { + return ''; + } + if (mxc.indexOf("mxc://") !== 0) { + if (allowDirectLinks) { + return mxc; + } else { return ''; } - if (mxc.indexOf("mxc://") !== 0) { - if (allowDirectLinks) { - return mxc; - } else { - return ''; - } - } - let serverAndMediaId = mxc.slice(6); // strips mxc:// - let prefix = "/_matrix/media/r0/download/"; - const params = {}; + } + let serverAndMediaId = mxc.slice(6); // strips mxc:// + let prefix = "/_matrix/media/r0/download/"; + const params = {}; - if (width) { - params.width = Math.round(width); - } - if (height) { - params.height = Math.round(height); - } - if (resizeMethod) { - params.method = resizeMethod; - } - if (utils.keys(params).length > 0) { - // these are thumbnailing params so they probably want the - // thumbnailing API... - prefix = "/_matrix/media/r0/thumbnail/"; - } + if (width) { + params.width = Math.round(width); + } + if (height) { + params.height = Math.round(height); + } + if (resizeMethod) { + params.method = resizeMethod; + } + if (utils.keys(params).length > 0) { + // these are thumbnailing params so they probably want the + // thumbnailing API... + prefix = "/_matrix/media/r0/thumbnail/"; + } - const fragmentOffset = serverAndMediaId.indexOf("#"); - let fragment = ""; - if (fragmentOffset >= 0) { - fragment = serverAndMediaId.substr(fragmentOffset); - serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); - } - return baseUrl + prefix + serverAndMediaId + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))) + fragment; - }, + const fragmentOffset = serverAndMediaId.indexOf("#"); + let fragment = ""; + if (fragmentOffset >= 0) { + fragment = serverAndMediaId.substr(fragmentOffset); + serverAndMediaId = serverAndMediaId.substr(0, fragmentOffset); + } + return baseUrl + prefix + serverAndMediaId + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))) + fragment; +} - /** - * Get an identicon URL from an arbitrary string. - * @param {string} baseUrl The base homeserver url which has a content repo. - * @param {string} identiconString The string to create an identicon for. - * @param {Number} width The desired width of the image in pixels. Default: 96. - * @param {Number} height The desired height of the image in pixels. Default: 96. - * @return {string} The complete URL to the identicon. - * @deprecated This is no longer in the specification. - */ - getIdenticonUri: function(baseUrl, identiconString, width, height) { - if (!identiconString) { - return null; - } - if (!width) { - width = 96; - } - if (!height) { - height = 96; - } - const params = { - width: width, - height: height, - }; +/** + * Get an identicon URL from an arbitrary string. + * @param {string} baseUrl The base homeserver url which has a content repo. + * @param {string} identiconString The string to create an identicon for. + * @param {Number} width The desired width of the image in pixels. Default: 96. + * @param {Number} height The desired height of the image in pixels. Default: 96. + * @return {string} The complete URL to the identicon. + * @deprecated This is no longer in the specification. + */ +export function getIdenticonUri(baseUrl, identiconString, width, height) { + if (!identiconString) { + return null; + } + if (!width) { + width = 96; + } + if (!height) { + height = 96; + } + const params = { + width: width, + height: height, + }; - const path = utils.encodeUri("/_matrix/media/unstable/identicon/$ident", { - $ident: identiconString, - }); - return baseUrl + path + - (utils.keys(params).length === 0 ? "" : - ("?" + utils.encodeParams(params))); - }, -}; + const path = utils.encodeUri("/_matrix/media/unstable/identicon/$ident", { + $ident: identiconString, + }); + return baseUrl + path + + (utils.keys(params).length === 0 ? "" : + ("?" + utils.encodeParams(params))); +} diff --git a/src/crypto/CrossSigning.js b/src/crypto/CrossSigning.js index 764f2c21e..b37fa6d43 100644 --- a/src/crypto/CrossSigning.js +++ b/src/crypto/CrossSigning.js @@ -20,9 +20,9 @@ limitations under the License. * @module crypto/CrossSigning */ -import {pkSign, pkVerify, encodeBase64, decodeBase64} from './olmlib'; +import {decodeBase64, encodeBase64, pkSign, pkVerify} from './olmlib'; import {EventEmitter} from 'events'; -import logger from '../logger'; +import {logger} from '../logger'; function publicKeyFromKeyInfo(keyInfo) { // `keys` is an object with { [`ed25519:${pubKey}`]: pubKey } diff --git a/src/crypto/DeviceList.js b/src/crypto/DeviceList.js index 7087bac43..44aa05735 100644 --- a/src/crypto/DeviceList.js +++ b/src/crypto/DeviceList.js @@ -24,12 +24,11 @@ limitations under the License. */ import {EventEmitter} from 'events'; - -import logger from '../logger'; -import DeviceInfo from './deviceinfo'; +import {logger} from '../logger'; +import {DeviceInfo} from './deviceinfo'; import {CrossSigningInfo} from './CrossSigning'; -import olmlib from './olmlib'; -import IndexedDBCryptoStore from './store/indexeddb-crypto-store'; +import * as olmlib from './olmlib'; +import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; import {defer, sleep} from '../utils'; @@ -63,7 +62,7 @@ const TRACKING_STATUS_UP_TO_DATE = 3; /** * @alias module:crypto/DeviceList */ -export default class DeviceList extends EventEmitter { +export class DeviceList extends EventEmitter { constructor(baseApis, cryptoStore, olmDevice) { super(); diff --git a/src/crypto/OlmDevice.js b/src/crypto/OlmDevice.js index b86b4f858..7da0be7d1 100644 --- a/src/crypto/OlmDevice.js +++ b/src/crypto/OlmDevice.js @@ -1,6 +1,7 @@ /* Copyright 2016 OpenMarket Ltd Copyright 2017, 2019 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,8 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../logger'; -import IndexedDBCryptoStore from './store/indexeddb-crypto-store'; +import {logger} from '../logger'; +import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; // The maximum size of an event is 65K, and we base64 the content, so this is a // reasonable approximation to the biggest plaintext we can encrypt. @@ -69,7 +70,7 @@ function checkPayloadLength(payloadString) { * @property {string} deviceCurve25519Key Curve25519 key for the account * @property {string} deviceEd25519Key Ed25519 key for the account */ -function OlmDevice(cryptoStore) { +export function OlmDevice(cryptoStore) { this._cryptoStore = cryptoStore; this._pickleKey = "DEFAULT_KEY"; @@ -1139,6 +1140,3 @@ OlmDevice.prototype.verifySignature = function( util.ed25519_verify(key, message, signature); }); }; - -/** */ -module.exports = OlmDevice; diff --git a/src/crypto/OutgoingRoomKeyRequestManager.js b/src/crypto/OutgoingRoomKeyRequestManager.js index ef435e9c8..803791df4 100644 --- a/src/crypto/OutgoingRoomKeyRequestManager.js +++ b/src/crypto/OutgoingRoomKeyRequestManager.js @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../logger'; -import utils from '../utils'; +import {logger} from '../logger'; +import * as utils from '../utils'; /** * Internal module. Management of outgoing room key requests. @@ -75,7 +75,7 @@ const ROOM_KEY_REQUEST_STATES = { CANCELLATION_PENDING_AND_WILL_RESEND: 3, }; -export default class OutgoingRoomKeyRequestManager { +export class OutgoingRoomKeyRequestManager { constructor(baseApis, deviceId, cryptoStore) { this._baseApis = baseApis; this._deviceId = deviceId; diff --git a/src/crypto/RoomList.js b/src/crypto/RoomList.js index b8c87dd1f..6a3c6c22f 100644 --- a/src/crypto/RoomList.js +++ b/src/crypto/RoomList.js @@ -20,12 +20,12 @@ limitations under the License. * Manages the list of encrypted rooms */ -import IndexedDBCryptoStore from './store/indexeddb-crypto-store'; +import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; /** * @alias module:crypto/RoomList */ -export default class RoomList { +export class RoomList { constructor(cryptoStore) { this._cryptoStore = cryptoStore; diff --git a/src/crypto/SecretStorage.js b/src/crypto/SecretStorage.js index db984b950..075156afa 100644 --- a/src/crypto/SecretStorage.js +++ b/src/crypto/SecretStorage.js @@ -15,10 +15,10 @@ limitations under the License. */ import {EventEmitter} from 'events'; -import logger from '../logger'; -import olmlib from './olmlib'; -import { randomString } from '../randomstring'; -import { pkVerify } from './olmlib'; +import {logger} from '../logger'; +import * as olmlib from './olmlib'; +import {pkVerify} from './olmlib'; +import {randomString} from '../randomstring'; export const SECRET_STORAGE_ALGORITHM_V1 = "m.secret_storage.v1.curve25519-aes-sha2"; @@ -26,7 +26,7 @@ export const SECRET_STORAGE_ALGORITHM_V1 = "m.secret_storage.v1.curve25519-aes-s * Implements Secure Secret Storage and Sharing (MSC1946) * @module crypto/SecretStorage */ -export default class SecretStorage extends EventEmitter { +export class SecretStorage extends EventEmitter { constructor(baseApis, cryptoCallbacks, crossSigningInfo) { super(); this._baseApis = baseApis; diff --git a/src/crypto/algorithms/base.js b/src/crypto/algorithms/base.js index d5e38f477..d1cba5f30 100644 --- a/src/crypto/algorithms/base.js +++ b/src/crypto/algorithms/base.js @@ -50,7 +50,7 @@ export const DECRYPTION_CLASSES = {}; * @param {string} params.roomId The ID of the room we will be sending to * @param {object} params.config The body of the m.room.encryption event */ -class EncryptionAlgorithm { +export class EncryptionAlgorithm { constructor(params) { this._userId = params.userId; this._deviceId = params.deviceId; @@ -84,7 +84,6 @@ class EncryptionAlgorithm { onRoomMembership(event, member, oldMembership) { } } -export {EncryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272 /** * base type for decryption implementations @@ -98,7 +97,7 @@ export {EncryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272 * @param {string=} params.roomId The ID of the room we will be receiving * from. Null for to-device events. */ -class DecryptionAlgorithm { +export class DecryptionAlgorithm { constructor(params) { this._userId = params.userId; this._crypto = params.crypto; @@ -160,7 +159,6 @@ class DecryptionAlgorithm { throw new Error("shareKeysWithDevice not supported for this DecryptionAlgorithm"); } } -export {DecryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272 /** * Exception thrown when decryption fails @@ -173,7 +171,7 @@ export {DecryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272 * * @extends Error */ -class DecryptionError extends Error { +export class DecryptionError extends Error { constructor(code, msg, details) { super(msg); this.code = code; @@ -181,7 +179,6 @@ class DecryptionError extends Error { this.detailedString = _detailedStringForDecryptionError(this, details); } } -export {DecryptionError}; // https://github.com/jsdoc3/jsdoc/issues/1272 function _detailedStringForDecryptionError(err, details) { let result = err.name + '[msg: ' + err.message; diff --git a/src/crypto/algorithms/index.js b/src/crypto/algorithms/index.js index ce64b3b11..6895b3dcb 100644 --- a/src/crypto/algorithms/index.js +++ b/src/crypto/algorithms/index.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,22 +20,7 @@ limitations under the License. * @module crypto/algorithms */ -const base = require("./base"); +import "./olm"; +import "./megolm"; -require("./olm"); -require("./megolm"); - -/** - * @see module:crypto/algorithms/base.ENCRYPTION_CLASSES - */ -module.exports.ENCRYPTION_CLASSES = base.ENCRYPTION_CLASSES; - -/** - * @see module:crypto/algorithms/base.DECRYPTION_CLASSES - */ -module.exports.DECRYPTION_CLASSES = base.DECRYPTION_CLASSES; - -/** - * @see module:crypto/algorithms/base.DecryptionError - */ -module.exports.DecryptionError = base.DecryptionError; +export * from "./base"; diff --git a/src/crypto/algorithms/megolm.js b/src/crypto/algorithms/megolm.js index 8c60adf5c..5bfd5eae0 100644 --- a/src/crypto/algorithms/megolm.js +++ b/src/crypto/algorithms/megolm.js @@ -22,11 +22,17 @@ limitations under the License. * @module crypto/algorithms/megolm */ -import logger from '../../logger'; - -const utils = require("../../utils"); -const olmlib = require("../olmlib"); -const base = require("./base"); +import {logger} from '../../logger'; +import * as utils from "../../utils"; +import {polyfillSuper} from "../../utils"; +import * as olmlib from "../olmlib"; +import { + DecryptionAlgorithm, + DecryptionError, + EncryptionAlgorithm, + registerAlgorithm, + UnknownDeviceError, +} from "./base"; /** * @private @@ -128,13 +134,13 @@ OutboundSessionInfo.prototype.sharedWithTooManyDevices = function( * Megolm encryption implementation * * @constructor - * @extends {module:crypto/algorithms/base.EncryptionAlgorithm} + * @extends {module:crypto/algorithms/EncryptionAlgorithm} * * @param {object} params parameters, as per - * {@link module:crypto/algorithms/base.EncryptionAlgorithm} + * {@link module:crypto/algorithms/EncryptionAlgorithm} */ function MegolmEncryption(params) { - base.EncryptionAlgorithm.call(this, params); + polyfillSuper(this, EncryptionAlgorithm, params); // the most recent attempt to set up a session. This is used to serialise // the session setups, so that we have a race-free view of which session we @@ -160,7 +166,7 @@ function MegolmEncryption(params) { this._sessionRotationPeriodMsgs = params.config.rotation_period_msgs; } } -utils.inherits(MegolmEncryption, base.EncryptionAlgorithm); +utils.inherits(MegolmEncryption, EncryptionAlgorithm); /** * @private @@ -643,7 +649,7 @@ MegolmEncryption.prototype._checkForUnknownDevices = function(devicesInRoom) { if (Object.keys(unknownDevices).length) { // it'd be kind to pass unknownDevices up to the user in this error - throw new base.UnknownDeviceError( + throw new UnknownDeviceError( "This room contains unknown devices which have not been verified. " + "We strongly recommend you verify them before continuing.", unknownDevices); } @@ -703,13 +709,13 @@ MegolmEncryption.prototype._getDevicesInRoom = async function(room) { * Megolm decryption implementation * * @constructor - * @extends {module:crypto/algorithms/base.DecryptionAlgorithm} + * @extends {module:crypto/algorithms/DecryptionAlgorithm} * * @param {object} params parameters, as per - * {@link module:crypto/algorithms/base.DecryptionAlgorithm} + * {@link module:crypto/algorithms/DecryptionAlgorithm} */ function MegolmDecryption(params) { - base.DecryptionAlgorithm.call(this, params); + polyfillSuper(this, DecryptionAlgorithm, params); // events which we couldn't decrypt due to unknown sessions / indexes: map from // senderKey|sessionId to Set of MatrixEvents @@ -718,7 +724,7 @@ function MegolmDecryption(params) { // this gets stubbed out by the unit tests. this.olmlib = olmlib; } -utils.inherits(MegolmDecryption, base.DecryptionAlgorithm); +utils.inherits(MegolmDecryption, DecryptionAlgorithm); /** * @inheritdoc @@ -736,7 +742,7 @@ MegolmDecryption.prototype.decryptEvent = async function(event) { if (!content.sender_key || !content.session_id || !content.ciphertext ) { - throw new base.DecryptionError( + throw new DecryptionError( "MEGOLM_MISSING_FIELDS", "Missing fields in input", ); @@ -764,7 +770,7 @@ MegolmDecryption.prototype.decryptEvent = async function(event) { errorCode = 'OLM_UNKNOWN_MESSAGE_INDEX'; } - throw new base.DecryptionError( + throw new DecryptionError( errorCode, e ? e.toString() : "Unknown Error: Error is undefined", { session: content.sender_key + '|' + content.session_id, @@ -781,7 +787,7 @@ MegolmDecryption.prototype.decryptEvent = async function(event) { // event is still in the pending list; if not, a retry will have been // scheduled, so we needn't send out the request here.) this._requestKeysForEvent(event); - throw new base.DecryptionError( + throw new DecryptionError( "MEGOLM_UNKNOWN_INBOUND_SESSION_ID", "The sender's device has not sent us the keys for this message.", { @@ -800,7 +806,7 @@ MegolmDecryption.prototype.decryptEvent = async function(event) { // (this is somewhat redundant, since the megolm session is scoped to the // room, so neither the sender nor a MITM can lie about the room_id). if (payload.room_id !== event.getRoomId()) { - throw new base.DecryptionError( + throw new DecryptionError( "MEGOLM_BAD_ROOM", "Message intended for room " + payload.room_id, ); @@ -1125,6 +1131,6 @@ MegolmDecryption.prototype._retryDecryption = async function(senderKey, sessionI return !this._pendingEvents[k]; }; -base.registerAlgorithm( +registerAlgorithm( olmlib.MEGOLM_ALGORITHM, MegolmEncryption, MegolmDecryption, ); diff --git a/src/crypto/algorithms/olm.js b/src/crypto/algorithms/olm.js index 25fb21d94..ea7cc7f09 100644 --- a/src/crypto/algorithms/olm.js +++ b/src/crypto/algorithms/olm.js @@ -20,29 +20,31 @@ limitations under the License. * * @module crypto/algorithms/olm */ -import logger from '../../logger'; -const utils = require("../../utils"); -const olmlib = require("../olmlib"); -const DeviceInfo = require("../deviceinfo"); -const DeviceVerification = DeviceInfo.DeviceVerification; -const base = require("./base"); +import {logger} from '../../logger'; +import * as utils from "../../utils"; +import {polyfillSuper} from "../../utils"; +import * as olmlib from "../olmlib"; +import {DeviceInfo} from "../deviceinfo"; +import {DecryptionAlgorithm, DecryptionError, EncryptionAlgorithm, registerAlgorithm} from "./base"; + +const DeviceVerification = DeviceInfo.DeviceVerification; /** * Olm encryption implementation * * @constructor - * @extends {module:crypto/algorithms/base.EncryptionAlgorithm} + * @extends {module:crypto/algorithms/EncryptionAlgorithm} * * @param {object} params parameters, as per - * {@link module:crypto/algorithms/base.EncryptionAlgorithm} + * {@link module:crypto/algorithms/EncryptionAlgorithm} */ function OlmEncryption(params) { - base.EncryptionAlgorithm.call(this, params); + polyfillSuper(this, EncryptionAlgorithm, params); this._sessionPrepared = false; this._prepPromise = null; } -utils.inherits(OlmEncryption, base.EncryptionAlgorithm); +utils.inherits(OlmEncryption, EncryptionAlgorithm); /** * @private @@ -143,14 +145,14 @@ OlmEncryption.prototype.encryptMessage = async function(room, eventType, content * Olm decryption implementation * * @constructor - * @extends {module:crypto/algorithms/base.DecryptionAlgorithm} + * @extends {module:crypto/algorithms/DecryptionAlgorithm} * @param {object} params parameters, as per - * {@link module:crypto/algorithms/base.DecryptionAlgorithm} + * {@link module:crypto/algorithms/DecryptionAlgorithm} */ function OlmDecryption(params) { - base.DecryptionAlgorithm.call(this, params); + polyfillSuper(this, DecryptionAlgorithm, params); } -utils.inherits(OlmDecryption, base.DecryptionAlgorithm); +utils.inherits(OlmDecryption, DecryptionAlgorithm); /** * @inheritdoc @@ -168,14 +170,14 @@ OlmDecryption.prototype.decryptEvent = async function(event) { const ciphertext = content.ciphertext; if (!ciphertext) { - throw new base.DecryptionError( + throw new DecryptionError( "OLM_MISSING_CIPHERTEXT", "Missing ciphertext", ); } if (!(this._olmDevice.deviceCurve25519Key in ciphertext)) { - throw new base.DecryptionError( + throw new DecryptionError( "OLM_NOT_INCLUDED_IN_RECIPIENTS", "Not included in recipients", ); @@ -186,7 +188,7 @@ OlmDecryption.prototype.decryptEvent = async function(event) { try { payloadString = await this._decryptMessage(deviceKey, message); } catch (e) { - throw new base.DecryptionError( + throw new DecryptionError( "OLM_BAD_ENCRYPTED_MESSAGE", "Bad Encrypted Message", { sender: deviceKey, @@ -200,14 +202,14 @@ OlmDecryption.prototype.decryptEvent = async function(event) { // check that we were the intended recipient, to avoid unknown-key attack // https://github.com/vector-im/vector-web/issues/2483 if (payload.recipient != this._userId) { - throw new base.DecryptionError( + throw new DecryptionError( "OLM_BAD_RECIPIENT", "Message was intented for " + payload.recipient, ); } if (payload.recipient_keys.ed25519 != this._olmDevice.deviceEd25519Key) { - throw new base.DecryptionError( + throw new DecryptionError( "OLM_BAD_RECIPIENT_KEY", "Message not intended for this device", { intended: payload.recipient_keys.ed25519, @@ -221,7 +223,7 @@ OlmDecryption.prototype.decryptEvent = async function(event) { // (this check is also provided via the sender's embedded ed25519 key, // which is checked elsewhere). if (payload.sender != event.getSender()) { - throw new base.DecryptionError( + throw new DecryptionError( "OLM_FORWARDED_MESSAGE", "Message forwarded from " + payload.sender, { reported_sender: event.getSender(), @@ -231,7 +233,7 @@ OlmDecryption.prototype.decryptEvent = async function(event) { // Olm events intended for a room have a room_id. if (payload.room_id !== event.getRoomId()) { - throw new base.DecryptionError( + throw new DecryptionError( "OLM_BAD_ROOM", "Message intended for room " + payload.room_id, { reported_room: event.room_id, @@ -334,4 +336,4 @@ OlmDecryption.prototype._decryptMessage = async function( }; -base.registerAlgorithm(olmlib.OLM_ALGORITHM, OlmEncryption, OlmDecryption); +registerAlgorithm(olmlib.OLM_ALGORITHM, OlmEncryption, OlmDecryption); diff --git a/src/crypto/deviceinfo.js b/src/crypto/deviceinfo.js index 2dbb2393d..34bffba8a 100644 --- a/src/crypto/deviceinfo.js +++ b/src/crypto/deviceinfo.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -44,7 +45,7 @@ limitations under the License. * * @param {string} deviceId id of the device */ -function DeviceInfo(deviceId) { +export function DeviceInfo(deviceId) { // you can't change the deviceId Object.defineProperty(this, 'deviceId', { enumerable: true, @@ -167,5 +168,3 @@ DeviceInfo.DeviceVerification = { const DeviceVerification = DeviceInfo.DeviceVerification; -/** */ -module.exports = DeviceInfo; diff --git a/src/crypto/index.js b/src/crypto/index.js index f246299c7..760793adc 100644 --- a/src/crypto/index.js +++ b/src/crypto/index.js @@ -22,38 +22,30 @@ limitations under the License. * @module crypto */ -const anotherjson = require('another-json'); +import anotherjson from "another-json"; import {EventEmitter} from 'events'; -import ReEmitter from '../ReEmitter'; +import {ReEmitter} from '../ReEmitter'; +import {logger} from '../logger'; +import * as utils from "../utils"; +import {sleep} from "../utils"; +import {OlmDevice} from "./OlmDevice"; +import * as olmlib from "./olmlib"; +import {DeviceList} from "./DeviceList"; +import {DeviceInfo} from "./deviceinfo"; +import * as algorithms from "./algorithms"; +import {CrossSigningInfo, CrossSigningLevel, DeviceTrustLevel, UserTrustLevel} from './CrossSigning'; +import {SECRET_STORAGE_ALGORITHM_V1, SecretStorage} from './SecretStorage'; +import {OutgoingRoomKeyRequestManager} from './OutgoingRoomKeyRequestManager'; +import {IndexedDBCryptoStore} from './store/indexeddb-crypto-store'; +import {ScanQRCode, ShowQRCode} from './verification/QRCode'; +import {SAS} from './verification/SAS'; +import {keyFromPassphrase} from './key_passphrase'; +import {encodeRecoveryKey} from './recoverykey'; +import {VerificationRequest} from "./verification/request/VerificationRequest"; +import {InRoomChannel} from "./verification/request/InRoomChannel"; +import {ToDeviceChannel} from "./verification/request/ToDeviceChannel"; -import logger from '../logger'; -const utils = require("../utils"); -const OlmDevice = require("./OlmDevice"); -const olmlib = require("./olmlib"); -const algorithms = require("./algorithms"); -const DeviceInfo = require("./deviceinfo"); const DeviceVerification = DeviceInfo.DeviceVerification; -const DeviceList = require('./DeviceList').default; -import { - CrossSigningInfo, - UserTrustLevel, - DeviceTrustLevel, - CrossSigningLevel, -} from './CrossSigning'; -import SecretStorage, { SECRET_STORAGE_ALGORITHM_V1 } from './SecretStorage'; - -import OutgoingRoomKeyRequestManager from './OutgoingRoomKeyRequestManager'; -import IndexedDBCryptoStore from './store/indexeddb-crypto-store'; - -import {ShowQRCode, ScanQRCode} from './verification/QRCode'; -import SAS from './verification/SAS'; -import {sleep} from '../utils'; -import { keyFromPassphrase } from './key_passphrase'; -import { encodeRecoveryKey } from './recoverykey'; - -import VerificationRequest from "./verification/request/VerificationRequest"; -import InRoomChannel from "./verification/request/InRoomChannel"; -import ToDeviceChannel from "./verification/request/ToDeviceChannel"; const defaultVerificationMethods = { [ScanQRCode.NAME]: ScanQRCode, @@ -107,7 +99,7 @@ const KEY_BACKUP_KEYS_PER_REQUEST = 200; * Each element can either be a string from MatrixClient.verificationMethods * or a class that implements a verification method. */ -export default function Crypto(baseApis, sessionStore, userId, deviceId, +export function Crypto(baseApis, sessionStore, userId, deviceId, clientStore, cryptoStore, roomList, verificationMethods) { this._onDeviceListUserCrossSigningUpdated = this._onDeviceListUserCrossSigningUpdated.bind(this); diff --git a/src/crypto/key_passphrase.js b/src/crypto/key_passphrase.js index 0291a6e07..3e8455472 100644 --- a/src/crypto/key_passphrase.js +++ b/src/crypto/key_passphrase.js @@ -15,7 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { randomString } from '../randomstring'; +import {randomString} from '../randomstring'; const DEFAULT_ITERATIONS = 500000; diff --git a/src/crypto/olmlib.js b/src/crypto/olmlib.js index ab1b13e96..f413882d2 100644 --- a/src/crypto/olmlib.js +++ b/src/crypto/olmlib.js @@ -22,25 +22,24 @@ limitations under the License. * Utilities common to olm encryption algorithms */ -const anotherjson = require('another-json'); - -import logger from '../logger'; -const utils = require("../utils"); +import {logger} from '../logger'; +import * as utils from "../utils"; +import anotherjson from "another-json"; /** * matrix algorithm tag for olm */ -module.exports.OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2"; +export const OLM_ALGORITHM = "m.olm.v1.curve25519-aes-sha2"; /** * matrix algorithm tag for megolm */ -module.exports.MEGOLM_ALGORITHM = "m.megolm.v1.aes-sha2"; +export const MEGOLM_ALGORITHM = "m.megolm.v1.aes-sha2"; /** * matrix algorithm tag for megolm backups */ -module.exports.MEGOLM_BACKUP_ALGORITHM = "m.megolm_backup.v1.curve25519-aes-sha2"; +export const MEGOLM_BACKUP_ALGORITHM = "m.megolm_backup.v1.curve25519-aes-sha2"; /** @@ -59,7 +58,7 @@ module.exports.MEGOLM_BACKUP_ALGORITHM = "m.megolm_backup.v1.curve25519-aes-sha2 * Returns a promise which resolves (to undefined) when the payload * has been encrypted into `resultsObject` */ -module.exports.encryptMessageForDevice = async function( +export async function encryptMessageForDevice( resultsObject, ourUserId, ourDeviceId, olmDevice, recipientUserId, recipientDevice, payloadFields, @@ -112,7 +111,7 @@ module.exports.encryptMessageForDevice = async function( resultsObject[deviceKey] = await olmDevice.encryptMessage( deviceKey, sessionId, JSON.stringify(payload), ); -}; +} /** * Try to make sure we have established olm sessions for the given devices. @@ -131,7 +130,7 @@ module.exports.encryptMessageForDevice = async function( * an Object mapping from userId to deviceId to * {@link module:crypto~OlmSessionResult} */ -module.exports.ensureOlmSessionsForDevices = async function( +export async function ensureOlmSessionsForDevices( olmDevice, baseApis, devicesByUser, force, ) { const devicesWithoutSession = [ @@ -263,12 +262,12 @@ module.exports.ensureOlmSessionsForDevices = async function( await Promise.all(promises); return result; -}; +} async function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceInfo) { const deviceId = deviceInfo.deviceId; try { - await _verifySignature( + await verifySignature( olmDevice, oneTimeKey, userId, deviceId, deviceInfo.getFingerprint(), ); @@ -315,7 +314,7 @@ async function _verifyKeyAndStartSession(olmDevice, oneTimeKey, userId, deviceIn * Returns a promise which resolves (to undefined) if the the signature is good, * or rejects with an Error if it is bad. */ -const _verifySignature = module.exports.verifySignature = async function( +export async function verifySignature( olmDevice, obj, signingUserId, signingDeviceId, signingKey, ) { const signKeyId = "ed25519:" + signingDeviceId; @@ -336,7 +335,7 @@ const _verifySignature = module.exports.verifySignature = async function( olmDevice.verifySignature( signingKey, json, signature, ); -}; +} /** * Sign a JSON object using public key cryptography @@ -348,7 +347,7 @@ const _verifySignature = module.exports.verifySignature = async function( * @param {string} pubkey The public key (ignored if key is a seed) * @returns {string} the signature for the object */ -module.exports.pkSign = function(obj, key, userId, pubkey) { +export function pkSign(obj, key, userId, pubkey) { let createdKey = false; if (key instanceof Uint8Array) { const keyObj = new global.Olm.PkSigning(); @@ -372,7 +371,7 @@ module.exports.pkSign = function(obj, key, userId, pubkey) { key.free(); } } -}; +} /** * Verify a signed JSON object @@ -380,7 +379,7 @@ module.exports.pkSign = function(obj, key, userId, pubkey) { * @param {string} pubkey The public key to use to verify * @param {string} userId The user ID who signed the object */ -module.exports.pkVerify = function(obj, pubkey, userId) { +export function pkVerify(obj, pubkey, userId) { const keyId = "ed25519:" + pubkey; if (!(obj.signatures && obj.signatures[userId] && obj.signatures[userId][keyId])) { throw new Error("No signature"); @@ -398,22 +397,22 @@ module.exports.pkVerify = function(obj, pubkey, userId) { if (unsigned) obj.unsigned = unsigned; util.free(); } -}; +} /** * Encode a typed array of uint8 as base64. * @param {Uint8Array} uint8Array The data to encode. * @return {string} The base64. */ -module.exports.encodeBase64 = function(uint8Array) { +export function encodeBase64(uint8Array) { return Buffer.from(uint8Array).toString("base64"); -}; +} /** * Decode a base64 string to a typed array of uint8. * @param {string} base64 The base64 to decode. * @return {Uint8Array} The decoded data. */ -module.exports.decodeBase64 = function(base64) { +export function decodeBase64(base64) { return Buffer.from(base64, "base64"); -}; +} diff --git a/src/crypto/store/indexeddb-crypto-store-backend.js b/src/crypto/store/indexeddb-crypto-store-backend.js index aeead378e..4e60466d4 100644 --- a/src/crypto/store/indexeddb-crypto-store-backend.js +++ b/src/crypto/store/indexeddb-crypto-store-backend.js @@ -15,8 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../../logger'; -import utils from '../../utils'; +import {logger} from '../../logger'; +import * as utils from "../../utils"; export const VERSION = 7; diff --git a/src/crypto/store/indexeddb-crypto-store.js b/src/crypto/store/indexeddb-crypto-store.js index 68c10aec1..e8b58e527 100644 --- a/src/crypto/store/indexeddb-crypto-store.js +++ b/src/crypto/store/indexeddb-crypto-store.js @@ -15,10 +15,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../../logger'; -import LocalStorageCryptoStore from './localStorage-crypto-store'; -import MemoryCryptoStore from './memory-crypto-store'; -import * as IndexedDBCryptoStoreBackend from './indexeddb-crypto-store-backend'; +import {logger} from '../../logger'; +import {LocalStorageCryptoStore} from './localStorage-crypto-store'; +import {MemoryCryptoStore} from './memory-crypto-store'; +import {Backend as IndexedDBCryptoStoreBackend} from './indexeddb-crypto-store-backend'; import {InvalidCryptoStoreError} from '../../errors'; import * as IndexedDBHelpers from "../../indexeddb-helpers"; @@ -34,7 +34,7 @@ import * as IndexedDBHelpers from "../../indexeddb-helpers"; * * @implements {module:crypto/store/base~CryptoStore} */ -export default class IndexedDBCryptoStore { +export class IndexedDBCryptoStore { /** * Create a new IndexedDBCryptoStore * diff --git a/src/crypto/store/localStorage-crypto-store.js b/src/crypto/store/localStorage-crypto-store.js index 0f304fbb1..5ce28d971 100644 --- a/src/crypto/store/localStorage-crypto-store.js +++ b/src/crypto/store/localStorage-crypto-store.js @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../../logger'; -import MemoryCryptoStore from './memory-crypto-store'; +import {logger} from '../../logger'; +import {MemoryCryptoStore} from './memory-crypto-store'; /** * Internal module. Partial localStorage backed storage for e2e. @@ -50,7 +50,7 @@ function keyEndToEndRoomsPrefix(roomId) { /** * @implements {module:crypto/store/base~CryptoStore} */ -export default class LocalStorageCryptoStore extends MemoryCryptoStore { +export class LocalStorageCryptoStore extends MemoryCryptoStore { constructor(webStore) { super(); this.store = webStore; diff --git a/src/crypto/store/memory-crypto-store.js b/src/crypto/store/memory-crypto-store.js index eca79f037..18bbd7097 100644 --- a/src/crypto/store/memory-crypto-store.js +++ b/src/crypto/store/memory-crypto-store.js @@ -15,8 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../../logger'; -import utils from '../../utils'; +import {logger} from '../../logger'; +import * as utils from "../../utils"; /** * Internal module. in-memory storage for e2e. @@ -27,7 +27,7 @@ import utils from '../../utils'; /** * @implements {module:crypto/store/base~CryptoStore} */ -export default class MemoryCryptoStore { +export class MemoryCryptoStore { constructor() { this._outgoingRoomKeyRequests = []; this._account = null; diff --git a/src/crypto/verification/Base.js b/src/crypto/verification/Base.js index 9720f4dc9..82505f7a3 100644 --- a/src/crypto/verification/Base.js +++ b/src/crypto/verification/Base.js @@ -21,13 +21,13 @@ limitations under the License. import {MatrixEvent} from '../../models/event'; import {EventEmitter} from 'events'; -import logger from '../../logger'; -import DeviceInfo from '../deviceinfo'; +import {logger} from '../../logger'; +import {DeviceInfo} from '../deviceinfo'; import {newTimeoutError} from "./Error"; const timeoutException = new Error("Verification timed out"); -export default class VerificationBase extends EventEmitter { +export class VerificationBase extends EventEmitter { /** * Base class for verification methods. * diff --git a/src/crypto/verification/QRCode.js b/src/crypto/verification/QRCode.js index d86e389b3..3650228bc 100644 --- a/src/crypto/verification/QRCode.js +++ b/src/crypto/verification/QRCode.js @@ -19,13 +19,8 @@ limitations under the License. * @module crypto/verification/QRCode */ -import Base from "./Base"; -import { - errorFactory, - newUserCancelledError, - newKeyMismatchError, - newUserMismatchError, -} from './Error'; +import {VerificationBase as Base} from "./Base"; +import {errorFactory, newKeyMismatchError, newUserCancelledError, newUserMismatchError} from './Error'; const MATRIXTO_REGEXP = /^(?:https?:\/\/)?(?:www\.)?matrix\.to\/#\/([#@!+][^?]+)\?(.+)$/; const KEY_REGEXP = /^key_([^:]+:.+)$/; diff --git a/src/crypto/verification/SAS.js b/src/crypto/verification/SAS.js index cbca5fd35..421025f4a 100644 --- a/src/crypto/verification/SAS.js +++ b/src/crypto/verification/SAS.js @@ -19,14 +19,14 @@ limitations under the License. * @module crypto/verification/SAS */ -import Base from "./Base"; +import {VerificationBase as Base} from "./Base"; import anotherjson from 'another-json'; import { errorFactory, - newUserCancelledError, - newUnknownMethodError, - newKeyMismatchError, newInvalidMessageError, + newKeyMismatchError, + newUnknownMethodError, + newUserCancelledError, } from './Error'; const EVENTS = [ @@ -185,7 +185,11 @@ function intersection(anArray, aSet) { * @alias module:crypto/verification/SAS * @extends {module:crypto/verification/Base} */ -export default class SAS extends Base { +export class SAS extends Base { + static get NAME() { + return "m.sas.v1"; + } + get events() { return EVENTS; } @@ -426,5 +430,3 @@ export default class SAS extends Base { }); } } - -SAS.NAME = "m.sas.v1"; diff --git a/src/crypto/verification/request/InRoomChannel.js b/src/crypto/verification/request/InRoomChannel.js index f8db518de..d89bb3741 100644 --- a/src/crypto/verification/request/InRoomChannel.js +++ b/src/crypto/verification/request/InRoomChannel.js @@ -15,7 +15,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import VerificationRequest, {REQUEST_TYPE, START_TYPE} from "./VerificationRequest"; +import {REQUEST_TYPE, START_TYPE, VerificationRequest} from "./VerificationRequest"; + const MESSAGE_TYPE = "m.room.message"; const M_REFERENCE = "m.reference"; const M_RELATES_TO = "m.relates_to"; @@ -24,7 +25,7 @@ const M_RELATES_TO = "m.relates_to"; * A key verification channel that sends verification events in the timeline of a room. * Uses the event id of the initial m.key.verification.request event as a transaction id. */ -export default class InRoomChannel { +export class InRoomChannel { /** * @param {MatrixClient} client the matrix client, to send messages with and get current user & device from. * @param {string} roomId id of the room where verification events should be posted in, should be a DM with the given user. diff --git a/src/crypto/verification/request/RequestCallbackChannel.js b/src/crypto/verification/request/RequestCallbackChannel.js index f1faf79a9..7b1b12504 100644 --- a/src/crypto/verification/request/RequestCallbackChannel.js +++ b/src/crypto/verification/request/RequestCallbackChannel.js @@ -19,7 +19,7 @@ limitations under the License. * This way, the VerificationRequest can update its state based on events sent by the verifier. * Anything that is not sending is just routing through to the wrapped channel. */ -export default class RequestCallbackChannel { +export class RequestCallbackChannel { constructor(request, channel) { this._request = request; this._channel = channel; diff --git a/src/crypto/verification/request/ToDeviceChannel.js b/src/crypto/verification/request/ToDeviceChannel.js index 6b280182c..4aa8cdaf9 100644 --- a/src/crypto/verification/request/ToDeviceChannel.js +++ b/src/crypto/verification/request/ToDeviceChannel.js @@ -15,24 +15,16 @@ See the License for the specific language governing permissions and limitations under the License. */ -import { randomString } from '../../../randomstring'; -import logger from '../../../logger'; -import VerificationRequest, { - PHASE_STARTED, - REQUEST_TYPE, - START_TYPE, - CANCEL_TYPE, -} from "./VerificationRequest"; +import {randomString} from '../../../randomstring'; +import {logger} from '../../../logger'; +import {CANCEL_TYPE, PHASE_STARTED, REQUEST_TYPE, START_TYPE, VerificationRequest} from "./VerificationRequest"; +import {errorFromEvent, newUnexpectedMessageError} from "../Error"; -import { - newUnexpectedMessageError, - errorFromEvent, -} from "../Error"; /** * A key verification channel that sends verification events over to_device messages. * Generates its own transaction ids. */ -export default class ToDeviceChannel { +export class ToDeviceChannel { // userId and devices of user we're about to verify constructor(client, userId, devices, transactionId = null, deviceId = null) { this._client = client; diff --git a/src/crypto/verification/request/VerificationRequest.js b/src/crypto/verification/request/VerificationRequest.js index ba63a479f..37a2211bb 100644 --- a/src/crypto/verification/request/VerificationRequest.js +++ b/src/crypto/verification/request/VerificationRequest.js @@ -15,15 +15,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../../../logger'; -import RequestCallbackChannel from "./RequestCallbackChannel"; +import {logger} from '../../../logger'; +import {RequestCallbackChannel} from "./RequestCallbackChannel"; import {EventEmitter} from 'events'; -import { - newUnknownMethodError, - newUnexpectedMessageError, - errorFromEvent, - errorFactory, -} from "../Error"; +import {errorFactory, errorFromEvent, newUnexpectedMessageError, newUnknownMethodError} from "../Error"; // the recommended amount of time before a verification request // should be (automatically) cancelled without user interaction @@ -57,7 +52,7 @@ export const PHASE_DONE = 6; * send and receive verification events are put in `InRoomChannel` or `ToDeviceChannel`. * @event "change" whenever the state of the request object has changed. */ -export default class VerificationRequest extends EventEmitter { +export class VerificationRequest extends EventEmitter { constructor(channel, verificationMethods, userId, client) { super(); this.channel = channel; diff --git a/src/filter-component.js b/src/filter-component.js index 38b1c8afd..a9a11411f 100644 --- a/src/filter-component.js +++ b/src/filter-component.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -45,7 +46,7 @@ function _matches_wildcard(actual_value, filter_value) { * @constructor * @param {Object} filter_json the definition of this filter JSON, e.g. { 'contains_url': true } */ -function FilterComponent(filter_json) { +export function FilterComponent(filter_json) { this.filter_json = filter_json; this.types = filter_json.types || null; @@ -141,6 +142,3 @@ FilterComponent.prototype.filter = function(events) { FilterComponent.prototype.limit = function() { return this.filter_json.limit !== undefined ? this.filter_json.limit : 10; }; - -/** The FilterComponent class */ -module.exports = FilterComponent; diff --git a/src/filter.js b/src/filter.js index a63fcee13..34cf41760 100644 --- a/src/filter.js +++ b/src/filter.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,7 +19,7 @@ limitations under the License. * @module filter */ -const FilterComponent = require("./filter-component"); +import {FilterComponent} from "./filter-component"; /** * @param {Object} obj @@ -45,7 +46,7 @@ function setProp(obj, keyNesting, val) { * @prop {string} userId The user ID of the filter * @prop {?string} filterId The filter ID */ -function Filter(userId, filterId) { +export function Filter(userId, filterId) { this.userId = userId; this.filterId = filterId; this.definition = {}; @@ -198,6 +199,3 @@ Filter.fromJson = function(userId, filterId, jsonObj) { filter.setDefinition(jsonObj); return filter; }; - -/** The Filter class */ -module.exports = Filter; diff --git a/src/http-api.js b/src/http-api.js index 0d6aecd1d..8a1cc75ae 100644 --- a/src/http-api.js +++ b/src/http-api.js @@ -19,15 +19,15 @@ limitations under the License. * This is an internal module. See {@link MatrixHttpApi} for the public class. * @module http-api */ -const parseContentType = require('content-type').parse; -const utils = require("./utils"); -import logger from './logger'; +import {parse as parseContentType} from "content-type"; +import * as utils from "./utils"; +import {logger} from './logger'; // we use our own implementation of setTimeout, so that if we get suspended in // the middle of a /sync, we cancel the sync as soon as we awake, rather than // waiting for the delay to elapse. -const callbacks = require("./realtime-callbacks"); +import * as callbacks from "./realtime-callbacks"; /* TODO: @@ -38,27 +38,27 @@ TODO: /** * A constant representing the URI path for release 0 of the Client-Server HTTP API. */ -module.exports.PREFIX_R0 = "/_matrix/client/r0"; +export const PREFIX_R0 = "/_matrix/client/r0"; /** * A constant representing the URI path for as-yet unspecified Client-Server HTTP APIs. */ -module.exports.PREFIX_UNSTABLE = "/_matrix/client/unstable"; +export const PREFIX_UNSTABLE = "/_matrix/client/unstable"; /** * URI path for v1 of the the identity API */ -module.exports.PREFIX_IDENTITY_V1 = "/_matrix/identity/api/v1"; +export const PREFIX_IDENTITY_V1 = "/_matrix/identity/api/v1"; /** * URI path for the v2 identity API */ -module.exports.PREFIX_IDENTITY_V2 = "/_matrix/identity/v2"; +export const PREFIX_IDENTITY_V2 = "/_matrix/identity/v2"; /** * URI path for the media repo API */ -module.exports.PREFIX_MEDIA_R0 = "/_matrix/media/r0"; +export const PREFIX_MEDIA_R0 = "/_matrix/media/r0"; /** * Construct a MatrixHttpApi. @@ -85,16 +85,16 @@ module.exports.PREFIX_MEDIA_R0 = "/_matrix/media/r0"; * @param {boolean} [opts.useAuthorizationHeader = false] Set to true to use * Authorization header instead of query param to send the access token to the server. */ -module.exports.MatrixHttpApi = function MatrixHttpApi(event_emitter, opts) { +export function MatrixHttpApi(event_emitter, opts) { utils.checkObjectHasKeys(opts, ["baseUrl", "request", "prefix"]); opts.onlyData = opts.onlyData || false; this.event_emitter = event_emitter; this.opts = opts; this.useAuthorizationHeader = Boolean(opts.useAuthorizationHeader); this.uploads = []; -}; +} -module.exports.MatrixHttpApi.prototype = { +MatrixHttpApi.prototype = { /** * Sets the baase URL for the identity server * @param {string} url The new base url @@ -698,7 +698,7 @@ module.exports.MatrixHttpApi.prototype = { if (req && req.abort) { req.abort(); } - defer.reject(new module.exports.MatrixError({ + defer.reject(new MatrixError({ error: "Locally timed out waiting for a response", errcode: "ORG.MATRIX.JSSDK_TIMEOUT", timeout: localTimeoutMs, @@ -836,7 +836,7 @@ function parseErrorResponse(response, body) { if (contentType) { if (contentType.type === 'application/json') { const jsonBody = typeof(body) === 'object' ? body : JSON.parse(body); - err = new module.exports.MatrixError(jsonBody); + err = new MatrixError(jsonBody); } else if (contentType.type === 'text/plain') { err = new Error(`Server returned ${httpStatus} error: ${body}`); } @@ -891,13 +891,12 @@ function getResponseContentType(response) { * @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) { +export function MatrixError(errorJson) { errorJson = errorJson || {}; this.errcode = errorJson.errcode; this.name = errorJson.errcode || "Unknown error code"; this.message = errorJson.error || "Unknown message"; this.data = errorJson; -}; -module.exports.MatrixError.prototype = Object.create(Error.prototype); -/** */ -module.exports.MatrixError.prototype.constructor = module.exports.MatrixError; +} +MatrixError.prototype = Object.create(Error.prototype); +MatrixError.prototype.constructor = MatrixError; diff --git a/src/indexeddb-worker.js b/src/indexeddb-worker.js index aa6312e2f..b51d90afd 100644 --- a/src/indexeddb-worker.js +++ b/src/indexeddb-worker.js @@ -1,5 +1,6 @@ /* Copyright 2017 Vector Creations Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,5 +21,5 @@ limitations under the License. */ /** The {@link module:indexeddb-store-worker~IndexedDBStoreWorker} class. */ -module.exports.IndexedDBStoreWorker = require("./store/indexeddb-store-worker.js"); +export {IndexedDBStoreWorker} from "./store/indexeddb-store-worker"; diff --git a/src/interactive-auth.js b/src/interactive-auth.js index eb9d9dbaa..e1b3b7bcf 100644 --- a/src/interactive-auth.js +++ b/src/interactive-auth.js @@ -18,10 +18,10 @@ limitations under the License. "use strict"; /** @module interactive-auth */ -const url = require("url"); -const utils = require("./utils"); -import logger from './logger'; +import url from "url"; +import * as utils from "./utils"; +import {logger} from './logger'; const EMAIL_STAGE_TYPE = "m.login.email.identity"; const MSISDN_STAGE_TYPE = "m.login.msisdn"; @@ -103,7 +103,7 @@ const MSISDN_STAGE_TYPE = "m.login.msisdn"; * attemptAuth promise. * */ -function InteractiveAuth(opts) { +export function InteractiveAuth(opts) { this._matrixClient = opts.matrixClient; this._data = opts.authData || {}; this._requestCallback = opts.doRequest; @@ -510,6 +510,3 @@ InteractiveAuth.prototype = { }, }; - -/** */ -module.exports = InteractiveAuth; diff --git a/src/logger.js b/src/logger.js index ee77c2918..b079dfd5f 100644 --- a/src/logger.js +++ b/src/logger.js @@ -1,5 +1,6 @@ /* Copyright 2018 André Jaenisch +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,7 +18,8 @@ limitations under the License. /** * @module logger */ -const log = require("loglevel"); + +import log from "loglevel"; // This is to demonstrate, that you can use any namespace you want. // Namespaces allow you to turn on/off the logging for specific parts of the @@ -25,12 +27,12 @@ const log = require("loglevel"); // An idea would be to control this via an environment variable (on Node.js). // See https://www.npmjs.com/package/debug to see how this could be implemented // Part of #332 is introducing a logging library in the first place. -const DEFAULT_NAME_SPACE = "matrix"; -const logger = log.getLogger(DEFAULT_NAME_SPACE); -logger.setLevel(log.levels.DEBUG); +const DEFAULT_NAMESPACE = "matrix"; /** * Drop-in replacement for console using {@link https://www.npmjs.com/package/loglevel|loglevel}. * Can be tailored down to specific use cases if needed. -*/ -module.exports = logger; + */ +export const logger = log.getLogger(DEFAULT_NAMESPACE); +logger.setLevel(log.levels.DEBUG); + diff --git a/src/matrix.js b/src/matrix.js index 244b10f24..a311d211c 100644 --- a/src/matrix.js +++ b/src/matrix.js @@ -17,127 +17,65 @@ limitations under the License. */ "use strict"; -/** The {@link module:ContentHelpers} object */ -module.exports.ContentHelpers = require("./content-helpers"); -/** The {@link module:models/event.MatrixEvent|MatrixEvent} class. */ -module.exports.MatrixEvent = require("./models/event").MatrixEvent; -/** The {@link module:models/event.EventStatus|EventStatus} enum. */ -module.exports.EventStatus = require("./models/event").EventStatus; -/** The {@link module:store/memory.MemoryStore|MemoryStore} class. */ -module.exports.MemoryStore = require("./store/memory").MemoryStore; -/** - * The {@link module:store/memory.MemoryStore|MemoryStore} class was previously - * exported as `MatrixInMemoryStore`, so this is preserved for SDK consumers. - * @deprecated Prefer `MemoryStore` going forward. - */ -module.exports.MatrixInMemoryStore = module.exports.MemoryStore; -/** The {@link module:store/indexeddb.IndexedDBStore|IndexedDBStore} class. */ -module.exports.IndexedDBStore = require("./store/indexeddb").IndexedDBStore; -/** The {@link module:store/indexeddb.IndexedDBStoreBackend|IndexedDBStoreBackend} class. */ -module.exports.IndexedDBStoreBackend = require("./store/indexeddb").IndexedDBStoreBackend; -/** The {@link module:sync-accumulator.SyncAccumulator|SyncAccumulator} class. */ -module.exports.SyncAccumulator = require("./sync-accumulator"); -/** The {@link module:http-api.MatrixHttpApi|MatrixHttpApi} class. */ -module.exports.MatrixHttpApi = require("./http-api").MatrixHttpApi; -/** The {@link module:http-api.MatrixError|MatrixError} class. */ -module.exports.MatrixError = require("./http-api").MatrixError; -/** The {@link module:errors.InvalidStoreError|InvalidStoreError} class. */ -module.exports.InvalidStoreError = require("./errors").InvalidStoreError; -/** The {@link module:client.MatrixClient|MatrixClient} class. */ -module.exports.MatrixClient = require("./client").MatrixClient; -/** The {@link module:models/room|Room} class. */ -module.exports.Room = require("./models/room"); -/** The {@link module:models/group|Group} class. */ -module.exports.Group = require("./models/group"); -/** The {@link module:models/event-timeline~EventTimeline} class. */ -module.exports.EventTimeline = require("./models/event-timeline"); -/** The {@link module:models/event-timeline-set~EventTimelineSet} class. */ -module.exports.EventTimelineSet = require("./models/event-timeline-set"); -/** The {@link module:models/room-member|RoomMember} class. */ -module.exports.RoomMember = require("./models/room-member"); -/** The {@link module:models/room-state~RoomState|RoomState} class. */ -module.exports.RoomState = require("./models/room-state"); -/** The {@link module:models/user~User|User} class. */ -module.exports.User = require("./models/user"); -/** The {@link module:scheduler~MatrixScheduler|MatrixScheduler} class. */ -module.exports.MatrixScheduler = require("./scheduler"); -/** The {@link module:store/session/webstorage~WebStorageSessionStore| - * WebStorageSessionStore} class. Work in progress; unstable. */ -module.exports.WebStorageSessionStore = require("./store/session/webstorage"); -/** True if crypto libraries are being used on this client. */ -module.exports.CRYPTO_ENABLED = require("./client").CRYPTO_ENABLED; -/** {@link module:content-repo|ContentRepo} utility functions. */ -module.exports.ContentRepo = require("./content-repo"); -/** The {@link module:filter~Filter|Filter} class. */ -module.exports.Filter = require("./filter"); -/** The {@link module:timeline-window~TimelineWindow} class. */ -module.exports.TimelineWindow = require("./timeline-window").TimelineWindow; -/** The {@link module:interactive-auth} class. */ -module.exports.InteractiveAuth = require("./interactive-auth"); -/** The {@link module:auto-discovery|AutoDiscovery} class. */ -module.exports.AutoDiscovery = require("./autodiscovery").AutoDiscovery; +import {MemoryCryptoStore} from "./crypto/store/memory-crypto-store"; +import {MemoryStore} from "./store/memory"; +import {MatrixScheduler} from "./scheduler"; +import {MatrixClient} from "./client"; -module.exports.SERVICE_TYPES = require('./service-types').SERVICE_TYPES; - -module.exports.MemoryCryptoStore = - require("./crypto/store/memory-crypto-store").default; -module.exports.IndexedDBCryptoStore = - require("./crypto/store/indexeddb-crypto-store").default; - -/** - * Create a new Matrix Call. - * @function - * @param {module:client.MatrixClient} client The MatrixClient instance to use. - * @param {string} roomId The room the call is in. - * @return {module:webrtc/call~MatrixCall} The Matrix call or null if the browser - * does not support WebRTC. - */ -module.exports.createNewMatrixCall = require("./webrtc/call").createNewMatrixCall; - - -/** - * Set a preferred audio output device to use for MatrixCalls - * @function - * @param {string=} deviceId the identifier for the device - * undefined treated as unset - */ -module.exports.setMatrixCallAudioOutput = require('./webrtc/call').setAudioOutput; -/** - * Set a preferred audio input device to use for MatrixCalls - * @function - * @param {string=} deviceId the identifier for the device - * undefined treated as unset - */ -module.exports.setMatrixCallAudioInput = require('./webrtc/call').setAudioInput; -/** - * Set a preferred video input device to use for MatrixCalls - * @function - * @param {string=} deviceId the identifier for the device - * undefined treated as unset - */ -module.exports.setMatrixCallVideoInput = require('./webrtc/call').setVideoInput; +export * from "./client"; +export * from "./http-api"; +export * from "./autodiscovery"; +export * from "./sync-accumulator"; +export * from "./errors"; +export * from "./models/event"; +export * from "./models/room"; +export * from "./models/group"; +export * from "./models/event-timeline"; +export * from "./models/event-timeline-set"; +export * from "./models/room-member"; +export * from "./models/room-state"; +export * from "./models/user"; +export * from "./scheduler"; +export * from "./filter"; +export * from "./timeline-window"; +export * from "./interactive-auth"; +export * from "./service-types"; +export * from "./store/memory"; +export * from "./store/indexeddb"; +export * from "./store/session/webstorage"; +export * from "./crypto/store/memory-crypto-store"; +export * from "./crypto/store/indexeddb-crypto-store"; +export const ContentHelpers = import("./content-helpers"); +export const ContentRepo = import("./content-repo"); +export { + createNewMatrixCall, + setAudioOutput as setMatrixCallAudioOutput, + setAudioInput as setMatrixCallAudioInput, + setVideoInput as setMatrixCallVideoInput, +} from "./webrtc/call"; // expose the underlying request object so different environments can use // different request libs (e.g. request or browser-request) -let request; +let requestInstance; + /** * The function used to perform HTTP requests. Only use this if you want to * use a different HTTP library, e.g. Angular's $http. This should * be set prior to calling {@link createClient}. * @param {requestFunction} r The request function to use. */ -module.exports.request = function(r) { - request = r; -}; +export function request(r) { + requestInstance = r; +} /** * Return the currently-set request function. * @return {requestFunction} The current request function. */ -module.exports.getRequest = function() { - return request; -}; +export function getRequest() { + return requestInstance; +} /** * Apply wrapping code around the request function. The wrapper function is @@ -145,15 +83,15 @@ module.exports.getRequest = function() { * previous value, along with the options and callback arguments. * @param {requestWrapperFunction} wrapper The wrapping function. */ -module.exports.wrapRequest = function(wrapper) { - const origRequest = request; - request = function(options, callback) { +export function wrapRequest(wrapper) { + const origRequest = requestInstance; + requestInstance = function(options, callback) { return wrapper(origRequest, options, callback); }; -}; +} -let cryptoStoreFactory = () => new module.exports.MemoryCryptoStore; +let cryptoStoreFactory = () => new MemoryCryptoStore; /** * Configure a different factory to be used for creating crypto stores @@ -161,9 +99,9 @@ let cryptoStoreFactory = () => new module.exports.MemoryCryptoStore; * @param {Function} fac a function which will return a new * {@link module:crypto.store.base~CryptoStore}. */ -module.exports.setCryptoStoreFactory = function(fac) { +export function setCryptoStoreFactory(fac) { cryptoStoreFactory = fac; -}; +} /** * Construct a Matrix Client. Similar to {@link module:client~MatrixClient} @@ -188,20 +126,20 @@ module.exports.setCryptoStoreFactory = function(fac) { * @see {@link module:client~MatrixClient} for the full list of options for * opts. */ -module.exports.createClient = function(opts) { +export function createClient(opts) { if (typeof opts === "string") { opts = { "baseUrl": opts, }; } opts.request = opts.request || request; - opts.store = opts.store || new module.exports.MemoryStore({ + opts.store = opts.store || new MemoryStore({ localStorage: global.localStorage, }); - opts.scheduler = opts.scheduler || new module.exports.MatrixScheduler(); + opts.scheduler = opts.scheduler || new MatrixScheduler(); opts.cryptoStore = opts.cryptoStore || cryptoStoreFactory(); - return new module.exports.MatrixClient(opts); -}; + return new MatrixClient(opts); +} /** * The request function interface for performing HTTP requests. This matches the diff --git a/src/models/event-context.js b/src/models/event-context.js index c2f298b99..84808f847 100644 --- a/src/models/event-context.js +++ b/src/models/event-context.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -33,7 +34,7 @@ limitations under the License. * * @constructor */ -function EventContext(ourEvent) { +export function EventContext(ourEvent) { this._timeline = [ourEvent]; this._ourEventIndex = 0; this._paginateTokens = {b: null, f: null}; @@ -113,7 +114,3 @@ EventContext.prototype.addEvents = function(events, atStart) { } }; -/** - * The EventContext class - */ -module.exports = EventContext; diff --git a/src/models/event-timeline-set.js b/src/models/event-timeline-set.js index 36f546bc2..7e808db81 100644 --- a/src/models/event-timeline-set.js +++ b/src/models/event-timeline-set.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,12 +18,13 @@ limitations under the License. /** * @module models/event-timeline-set */ -const EventEmitter = require("events").EventEmitter; -const utils = require("../utils"); -const EventTimeline = require("./event-timeline"); + +import {EventEmitter} from "events"; +import {EventTimeline} from "./event-timeline"; import {EventStatus} from "./event"; -import logger from '../logger'; -import Relations from './relations'; +import * as utils from "../utils"; +import {logger} from '../logger'; +import {Relations} from './relations'; // var DEBUG = false; const DEBUG = true; @@ -71,7 +73,7 @@ if (DEBUG) { * via `getRelationsForEvent`. * This feature is currently unstable and the API may change without notice. */ -function EventTimelineSet(room, opts) { +export function EventTimelineSet(room, opts) { this.room = room; this._timelineSupport = Boolean(opts.timelineSupport); @@ -815,11 +817,6 @@ EventTimelineSet.prototype.aggregateRelations = function(event) { } }; -/** - * The EventTimelineSet class. - */ -module.exports = EventTimelineSet; - /** * Fires whenever the timeline in a room is updated. * @event module:client~MatrixClient#"Room.timeline" diff --git a/src/models/event-timeline.js b/src/models/event-timeline.js index 63846cebd..e678d88e5 100644 --- a/src/models/event-timeline.js +++ b/src/models/event-timeline.js @@ -1,5 +1,6 @@ /* Copyright 2016, 2017 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,7 +20,7 @@ limitations under the License. * @module models/event-timeline */ -const RoomState = require("./room-state"); +import {RoomState} from "./room-state"; /** * Construct a new EventTimeline @@ -41,7 +42,7 @@ const RoomState = require("./room-state"); * @param {EventTimelineSet} eventTimelineSet the set of timelines this is part of * @constructor */ -function EventTimeline(eventTimelineSet) { +export function EventTimeline(eventTimelineSet) { this._eventTimelineSet = eventTimelineSet; this._roomId = eventTimelineSet.room ? eventTimelineSet.room.roomId : null; this._events = []; @@ -396,8 +397,3 @@ EventTimeline.prototype.toString = function() { return this._name; }; - -/** - * The EventTimeline class - */ -module.exports = EventTimeline; diff --git a/src/models/event.js b/src/models/event.js index 0d1b7048b..42ae71961 100644 --- a/src/models/event.js +++ b/src/models/event.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -22,15 +23,15 @@ limitations under the License. */ import {EventEmitter} from 'events'; -import utils from '../utils.js'; -import logger from '../logger'; +import * as utils from '../utils.js'; +import {logger} from '../logger'; /** * Enum for event statuses. * @readonly * @enum {string} */ -const EventStatus = { +export const EventStatus = { /** The event was not sent and will no longer be retried. */ NOT_SENT: "not_sent", @@ -48,7 +49,6 @@ const EventStatus = { /** The event was cancelled before it was successfully sent. */ CANCELLED: "cancelled", }; -module.exports.EventStatus = EventStatus; const interns = {}; function intern(str) { @@ -81,7 +81,7 @@ function intern(str) { * that getDirectionalContent() will return event.content and not event.prev_content. * Default: true. This property is experimental and may change. */ -module.exports.MatrixEvent = function MatrixEvent( +export const MatrixEvent = function( event, ) { // intern the values of matrix events to force share strings and reduce the @@ -156,10 +156,10 @@ module.exports.MatrixEvent = function MatrixEvent( */ this._retryDecryption = false; }; -utils.inherits(module.exports.MatrixEvent, EventEmitter); +utils.inherits(MatrixEvent, EventEmitter); -utils.extend(module.exports.MatrixEvent.prototype, { +utils.extend(MatrixEvent.prototype, { /** * Get the event_id for this event. diff --git a/src/models/group.js b/src/models/group.js index 9a4b9e989..74b86f53e 100644 --- a/src/models/group.js +++ b/src/models/group.js @@ -1,5 +1,6 @@ /* Copyright 2017 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,9 +18,9 @@ limitations under the License. /** * @module models/group */ -const EventEmitter = require("events").EventEmitter; -const utils = require("../utils"); +import * as utils from "../utils"; +import {EventEmitter} from "events"; /** * Construct a new Group. @@ -34,7 +35,7 @@ const utils = require("../utils"); * to the group, if myMembership is 'invite'. * @prop {string} inviter.userId The user ID of the inviter */ -function Group(groupId) { +export function Group(groupId) { this.groupId = groupId; this.name = null; this.avatarUrl = null; @@ -70,8 +71,6 @@ Group.prototype.setInviter = function(inviter) { this.inviter = inviter; }; -module.exports = Group; - /** * Fires whenever a group's profile information is updated. * This means the 'name' and 'avatarUrl' properties. diff --git a/src/models/relations.js b/src/models/relations.js index 81ead22de..fa0e2b85d 100644 --- a/src/models/relations.js +++ b/src/models/relations.js @@ -14,8 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import EventEmitter from 'events'; -import { EventStatus } from '../models/event'; +import {EventEmitter} from 'events'; +import {EventStatus} from '../models/event'; /** * A container for relation events that supports easy access to common ways of @@ -25,7 +25,7 @@ import { EventStatus } from '../models/event'; * The typical way to get one of these containers is via * EventTimelineSet#getRelationsForEvent. */ -export default class Relations extends EventEmitter { +export class Relations extends EventEmitter { /** * @param {String} relationType * The type of relation involved, such as "m.annotation", "m.reference", diff --git a/src/models/room-member.js b/src/models/room-member.js index d92267720..0e2489208 100644 --- a/src/models/room-member.js +++ b/src/models/room-member.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,10 +18,10 @@ limitations under the License. /** * @module models/room-member */ -const EventEmitter = require("events").EventEmitter; -const ContentRepo = require("../content-repo"); -const utils = require("../utils"); +import {EventEmitter} from "events"; +import * as ContentRepo from "../content-repo"; +import * as utils from "../utils"; /** * Construct a new room member. @@ -45,7 +46,7 @@ const utils = require("../utils"); * @prop {Object} events The events describing this RoomMember. * @prop {MatrixEvent} events.member The m.room.member event for this RoomMember. */ -function RoomMember(roomId, userId) { +export function RoomMember(roomId, userId) { this.roomId = roomId; this.userId = userId; this.typing = false; @@ -325,11 +326,6 @@ function calculateDisplayName(selfUserId, displayName, roomState) { return displayName; } -/** - * The RoomMember class. - */ -module.exports = RoomMember; - /** * Fires whenever any room member's name changes. * @event module:client~MatrixClient#"RoomMember.name" diff --git a/src/models/room-state.js b/src/models/room-state.js index cb1579f46..d248c8a32 100644 --- a/src/models/room-state.js +++ b/src/models/room-state.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,11 +18,11 @@ limitations under the License. /** * @module models/room-state */ -const EventEmitter = require("events").EventEmitter; -const utils = require("../utils"); -const RoomMember = require("./room-member"); -import logger from '../logger'; +import {EventEmitter} from "events"; +import {RoomMember} from "./room-member"; +import {logger} from '../logger'; +import * as utils from "../utils"; // possible statuses for out-of-band member loading const OOB_STATUS_NOTSTARTED = 1; @@ -62,7 +63,7 @@ const OOB_STATUS_FINISHED = 3; * events dictionary, keyed on the event type and then the state_key value. * @prop {string} paginationToken The pagination token for this state. */ -function RoomState(roomId, oobMemberFlags = undefined) { +export function RoomState(roomId, oobMemberFlags = undefined) { this.roomId = roomId; this.members = { // userId: RoomMember @@ -714,11 +715,6 @@ RoomState.prototype.mayTriggerNotifOfType = function(notifLevelKey, userId) { return member.powerLevel >= notifLevel; }; -/** - * The RoomState class. - */ -module.exports = RoomState; - function _updateThirdPartyTokenCache(roomState, memberEvent) { if (!memberEvent.getContent().third_party_invite) { diff --git a/src/models/room-summary.js b/src/models/room-summary.js index 7329c3e79..060559e38 100644 --- a/src/models/room-summary.js +++ b/src/models/room-summary.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -31,12 +32,8 @@ limitations under the License. * @param {string[]} info.aliases The list of aliases for this room. * @param {Number} info.timestamp The timestamp for this room. */ -function RoomSummary(roomId, info) { +export function RoomSummary(roomId, info) { this.roomId = roomId; this.info = info; } -/** - * The RoomSummary class. - */ -module.exports = RoomSummary; diff --git a/src/models/room.js b/src/models/room.js index 77f12e845..e5b92c7c1 100644 --- a/src/models/room.js +++ b/src/models/room.js @@ -19,19 +19,17 @@ limitations under the License. /** * @module models/room */ -const EventEmitter = require("events").EventEmitter; -const EventStatus = require("./event").EventStatus; -const RoomSummary = require("./room-summary"); -const RoomMember = require("./room-member"); -const MatrixEvent = require("./event").MatrixEvent; -const utils = require("../utils"); -const ContentRepo = require("../content-repo"); -const EventTimeline = require("./event-timeline"); -const EventTimelineSet = require("./event-timeline-set"); - -import logger from '../logger'; -import ReEmitter from '../ReEmitter'; +import {EventEmitter} from "events"; +import {EventTimelineSet} from "./event-timeline-set"; +import {EventTimeline} from "./event-timeline"; +import * as ContentRepo from "../content-repo"; +import * as utils from "../utils"; +import {EventStatus, MatrixEvent} from "./event"; +import {RoomMember} from "./room-member"; +import {RoomSummary} from "./room-summary"; +import {logger} from '../logger'; +import {ReEmitter} from '../ReEmitter'; // These constants are used as sane defaults when the homeserver doesn't support // the m.room_versions capability. In practice, KNOWN_SAFE_ROOM_VERSION should be @@ -120,7 +118,7 @@ function synthesizeReceipt(userId, event, receiptType) { * @prop {*} storageToken A token which a data store can use to remember * the state of the room. */ -function Room(roomId, client, myUserId, opts) { +export function Room(roomId, client, myUserId, opts) { opts = opts || {}; opts.pendingEventOrdering = opts.pendingEventOrdering || "chronological"; @@ -1911,11 +1909,6 @@ function memberNamesToRoomName(names, count = (names.length + 1)) { } } -/** - * The Room class. - */ -module.exports = Room; - /** * Fires when an event we had previously received is redacted. * diff --git a/src/models/search-result.js b/src/models/search-result.js index bab76fa83..28be3169e 100644 --- a/src/models/search-result.js +++ b/src/models/search-result.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,8 +20,8 @@ limitations under the License. * @module models/search-result */ -const EventContext = require("./event-context"); -const utils = require("../utils"); +import * as utils from "../utils"; +import {EventContext} from "./event-context"; /** * Construct a new SearchResult @@ -31,7 +32,7 @@ const utils = require("../utils"); * * @constructor */ -function SearchResult(rank, eventContext) { +export function SearchResult(rank, eventContext) { this.rank = rank; this.context = eventContext; } @@ -59,8 +60,3 @@ SearchResult.fromJson = function(jsonObj, eventMapper) { return new SearchResult(jsonObj.rank, context); }; - -/** - * The SearchResult class - */ -module.exports = SearchResult; diff --git a/src/models/user.js b/src/models/user.js index 5e6340f29..32b557793 100644 --- a/src/models/user.js +++ b/src/models/user.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,8 +18,9 @@ limitations under the License. /** * @module models/user */ - const EventEmitter = require("events").EventEmitter; - const utils = require("../utils"); + +import * as utils from "../utils"; +import {EventEmitter} from "events"; /** * Construct a new User. A User must have an ID and can optionally have extra @@ -45,7 +47,7 @@ limitations under the License. * @prop {Object} events The events describing this user. * @prop {MatrixEvent} events.presence The m.presence event for this user. */ -function User(userId) { +export function User(userId) { this.userId = userId; this.presence = "offline"; this.presenceStatusMsg = null; @@ -195,11 +197,6 @@ User.prototype._unstable_updateStatusMessage = function(event) { this.emit("User._unstable_statusMessage", this); }; -/** - * The User class. - */ -module.exports = User; - /** * Fires whenever any user's lastPresenceTs changes, * ie. whenever any presence event is received for a user. diff --git a/src/pushprocessor.js b/src/pushprocessor.js index 3d0fc2db5..4c7338417 100644 --- a/src/pushprocessor.js +++ b/src/pushprocessor.js @@ -80,7 +80,7 @@ const DEFAULT_OVERRIDE_RULES = [ * @constructor * @param {Object} client The Matrix client object to use */ -function PushProcessor(client) { +export function PushProcessor(client) { const cachedGlobToRegex = { // $glob: RegExp, }; @@ -503,6 +503,4 @@ PushProcessor.rewriteDefaultRules = function(incomingRules) { * noise. */ -/** The PushProcessor class. */ -module.exports = PushProcessor; diff --git a/src/realtime-callbacks.js b/src/realtime-callbacks.js index 7a4401257..a8887c92a 100644 --- a/src/realtime-callbacks.js +++ b/src/realtime-callbacks.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -24,7 +25,8 @@ limitations under the License. */ "use strict"; -import logger from './logger'; + +import {logger} from './logger'; // we schedule a callback at least this often, to check if we've missed out on // some wall-clock time due to being suspended. @@ -52,9 +54,9 @@ const debuglog = function() {}; * * @internal */ -module.exports.setNow = function(f) { +export function setNow(f) { _now = f || Date.now; -}; +} let _now = Date.now; /** @@ -67,7 +69,7 @@ let _now = Date.now; * @return {Number} an identifier for this callback, which may be passed into * clearTimeout later. */ -module.exports.setTimeout = function(func, delayMs) { +export function setTimeout(func, delayMs) { delayMs = delayMs || 0; if (delayMs < 0) { delayMs = 0; @@ -96,14 +98,14 @@ module.exports.setTimeout = function(func, delayMs) { _scheduleRealCallback(); return key; -}; +} /** * reimplementation of window.clearTimeout, which mirrors setTimeout * * @param {Number} key result from an earlier setTimeout call */ -module.exports.clearTimeout = function(key) { +export function clearTimeout(key) { if (_callbackList.length === 0) { return; } @@ -122,7 +124,7 @@ module.exports.clearTimeout = function(key) { if (i === 0) { _scheduleRealCallback(); } -}; +} // use the real global.setTimeout to schedule a callback to _runCallbacks. function _scheduleRealCallback() { diff --git a/src/scheduler.js b/src/scheduler.js index 85ce50fd3..07fef66e0 100644 --- a/src/scheduler.js +++ b/src/scheduler.js @@ -1,5 +1,6 @@ /* Copyright 2015, 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,8 +20,8 @@ limitations under the License. * of requests. * @module scheduler */ -const utils = require("./utils"); -import logger from './logger'; +import * as utils from "./utils"; +import {logger} from './logger'; const DEBUG = false; // set true to enable console logging. @@ -36,7 +37,7 @@ const DEBUG = false; // set true to enable console logging. * algorithm to apply when determining which events should be sent before the * given event. Defaults to {@link module:scheduler~MatrixScheduler.QUEUE_MESSAGES}. */ -function MatrixScheduler(retryAlgorithm, queueAlgorithm) { +export function MatrixScheduler(retryAlgorithm, queueAlgorithm) { this.retryAlgorithm = retryAlgorithm || MatrixScheduler.RETRY_BACKOFF_RATELIMIT; this.queueAlgorithm = queueAlgorithm || MatrixScheduler.QUEUE_MESSAGES; this._queues = { @@ -318,7 +319,3 @@ function debuglog() { * @return {Promise} Resolved/rejected depending on the outcome of the request. */ -/** - * The MatrixScheduler class. - */ -module.exports = MatrixScheduler; diff --git a/src/store/indexeddb-local-backend.js b/src/store/indexeddb-local-backend.js index 587382eb8..0a5aa93f6 100644 --- a/src/store/indexeddb-local-backend.js +++ b/src/store/indexeddb-local-backend.js @@ -1,6 +1,7 @@ /* Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,10 +16,10 @@ See the License for the specific language governing permissions and limitations under the License. */ -import SyncAccumulator from "../sync-accumulator"; -import utils from "../utils"; +import {SyncAccumulator} from "../sync-accumulator"; +import * as utils from "../utils"; import * as IndexedDBHelpers from "../indexeddb-helpers"; -import logger from '../logger'; +import {logger} from '../logger'; const VERSION = 3; @@ -122,7 +123,7 @@ function reqAsCursorPromise(req) { * @param {string=} dbName Optional database name. The same name must be used * to open the same database. */ -const LocalIndexedDBStoreBackend = function LocalIndexedDBStoreBackend( +export function LocalIndexedDBStoreBackend( indexedDBInterface, dbName, ) { this.indexedDB = indexedDBInterface; @@ -131,7 +132,7 @@ const LocalIndexedDBStoreBackend = function LocalIndexedDBStoreBackend( this._disconnected = true; this._syncAccumulator = new SyncAccumulator(); this._isNewlyCreated = false; -}; +} LocalIndexedDBStoreBackend.exists = function(indexedDB, dbName) { dbName = "matrix-js-sdk:" + (dbName || "default"); @@ -572,5 +573,3 @@ LocalIndexedDBStoreBackend.prototype = { await txnAsPromise(txn); }, }; - -export default LocalIndexedDBStoreBackend; diff --git a/src/store/indexeddb-remote-backend.js b/src/store/indexeddb-remote-backend.js index e17014fb2..a00b16977 100644 --- a/src/store/indexeddb-remote-backend.js +++ b/src/store/indexeddb-remote-backend.js @@ -1,6 +1,7 @@ /* Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,7 +16,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import logger from '../logger'; +import {logger} from '../logger'; import {defer} from '../utils'; /** @@ -30,7 +31,7 @@ import {defer} from '../utils'; * to open the same database. * @param {Object} workerApi The web worker compatible interface object */ -const RemoteIndexedDBStoreBackend = function RemoteIndexedDBStoreBackend( +export function RemoteIndexedDBStoreBackend( workerScript, dbName, workerApi, ) { this._workerScript = workerScript; @@ -45,7 +46,7 @@ const RemoteIndexedDBStoreBackend = function RemoteIndexedDBStoreBackend( // Once we start connecting, we keep the promise and re-use it // if we try to connect again this._startPromise = null; -}; +} RemoteIndexedDBStoreBackend.prototype = { @@ -194,5 +195,3 @@ RemoteIndexedDBStoreBackend.prototype = { } }, }; - -export default RemoteIndexedDBStoreBackend; diff --git a/src/store/indexeddb-store-worker.js b/src/store/indexeddb-store-worker.js index e652b9a4e..5c1971bb0 100644 --- a/src/store/indexeddb-store-worker.js +++ b/src/store/indexeddb-store-worker.js @@ -1,6 +1,7 @@ /* Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -15,8 +16,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import LocalIndexedDBStoreBackend from "./indexeddb-local-backend.js"; -import logger from '../logger'; +import {LocalIndexedDBStoreBackend} from "./indexeddb-local-backend.js"; +import {logger} from '../logger'; /** * This class lives in the webworker and drives a LocalIndexedDBStoreBackend @@ -33,7 +34,7 @@ import logger from '../logger'; * avoid a dependency on the whole js-sdk. * */ -class IndexedDBStoreWorker { +export class IndexedDBStoreWorker { /** * @param {function} postMessage The web worker postMessage function that * should be used to communicate back to the main script. @@ -143,5 +144,3 @@ class IndexedDBStoreWorker { }); } } - -module.exports = IndexedDBStoreWorker; diff --git a/src/store/indexeddb.js b/src/store/indexeddb.js index c8eec104c..9cde4467d 100644 --- a/src/store/indexeddb.js +++ b/src/store/indexeddb.js @@ -1,6 +1,7 @@ /* Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -18,13 +19,13 @@ limitations under the License. /* eslint-disable babel/no-invalid-this */ import {MemoryStore} from "./memory"; -import utils from "../utils"; +import * as utils from "../utils"; import {EventEmitter} from 'events'; -import LocalIndexedDBStoreBackend from "./indexeddb-local-backend.js"; -import RemoteIndexedDBStoreBackend from "./indexeddb-remote-backend.js"; -import User from "../models/user"; +import {LocalIndexedDBStoreBackend} from "./indexeddb-local-backend.js"; +import {RemoteIndexedDBStoreBackend} from "./indexeddb-remote-backend.js"; +import {User} from "../models/user"; import {MatrixEvent} from "../models/event"; -import logger from '../logger'; +import {logger} from '../logger'; /** * This is an internal module. See {@link IndexedDBStore} for the public class. @@ -81,7 +82,7 @@ const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes * this API if you need to perform specific indexeddb actions like deleting the * database. */ -const IndexedDBStore = function IndexedDBStore(opts) { +export function IndexedDBStore(opts) { MemoryStore.call(this, opts); if (!opts.indexedDB) { @@ -111,7 +112,7 @@ const IndexedDBStore = function IndexedDBStore(opts) { this._userModifiedMap = { // user_id : timestamp }; -}; +} utils.inherits(IndexedDBStore, MemoryStore); utils.extend(IndexedDBStore.prototype, EventEmitter.prototype); @@ -273,8 +274,6 @@ IndexedDBStore.prototype.storeClientOptions = degradable(function(options) { return this.backend.storeClientOptions(options); }, "storeClientOptions"); -module.exports.IndexedDBStore = IndexedDBStore; - /** * All member functions of `IndexedDBStore` that access the backend use this wrapper to * watch for failures after initial store startup, including `QuotaExceededError` as diff --git a/src/store/memory.js b/src/store/memory.js index feeb56501..7ec2a701f 100644 --- a/src/store/memory.js +++ b/src/store/memory.js @@ -2,6 +2,7 @@ Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,8 +21,9 @@ limitations under the License. * This is an internal module. See {@link MemoryStore} for the public class. * @module store/memory */ -const utils = require("../utils"); -const User = require("../models/user"); + +import {User} from "../models/user"; +import * as utils from "../utils"; /** * Construct a new in-memory data store for the Matrix Client. @@ -30,7 +32,7 @@ const User = require("../models/user"); * @param {LocalStorage} opts.localStorage The local storage instance to persist * some forms of data such as tokens. Rooms will NOT be stored. */ -module.exports.MemoryStore = function MemoryStore(opts) { +export function MemoryStore(opts) { opts = opts || {}; this.rooms = { // roomId: Room @@ -55,9 +57,9 @@ module.exports.MemoryStore = function MemoryStore(opts) { // roomId: [member events] }; this._clientOptions = {}; -}; +} -module.exports.MemoryStore.prototype = { +MemoryStore.prototype = { /** * Retrieve the token to stream from. diff --git a/src/store/session/webstorage.js b/src/store/session/webstorage.js index e379b2fae..325359abe 100644 --- a/src/store/session/webstorage.js +++ b/src/store/session/webstorage.js @@ -2,6 +2,7 @@ Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 New Vector Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -21,8 +22,8 @@ limitations under the License. * @module store/session/webstorage */ -const utils = require("../../utils"); -import logger from '../../logger'; +import * as utils from "../../utils"; +import {logger} from '../../logger'; const DEBUG = false; // set true to enable console logging. const E2E_PREFIX = "session.e2e."; @@ -36,7 +37,7 @@ const E2E_PREFIX = "session.e2e."; * @throws if the supplied 'store' does not meet the Storage interface of the * WebStorage API. */ -function WebStorageSessionStore(webStore) { +export function WebStorageSessionStore(webStore) { this.store = webStore; if (!utils.isFunction(webStore.getItem) || !utils.isFunction(webStore.setItem) || @@ -261,6 +262,3 @@ function debuglog() { logger.log(...arguments); } } - -/** */ -module.exports = WebStorageSessionStore; diff --git a/src/store/stub.js b/src/store/stub.js index 2ab2256cd..6f74848f7 100644 --- a/src/store/stub.js +++ b/src/store/stub.js @@ -2,6 +2,7 @@ Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,7 +26,7 @@ limitations under the License. * Construct a stub store. This does no-ops on most store methods. * @constructor */ -function StubStore() { +export function StubStore() { this.fromToken = null; } @@ -289,6 +290,3 @@ StubStore.prototype = { return Promise.resolve(); }, }; - -/** Stub Store class. */ -module.exports = StubStore; diff --git a/src/sync-accumulator.js b/src/sync-accumulator.js index 8d9b3b787..2f7ad30bf 100644 --- a/src/sync-accumulator.js +++ b/src/sync-accumulator.js @@ -1,6 +1,7 @@ /* Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -20,9 +21,8 @@ limitations under the License. * @module sync-accumulator */ -import utils from "./utils"; -import logger from './logger'; - +import {logger} from './logger'; +import {deepCopy} from "./utils"; /** * The purpose of this class is to accumulate /sync responses such that a @@ -34,7 +34,7 @@ import logger from './logger'; * be loaded from disk and incremental syncs can be performed on the server, * rather than asking the server to do an initial sync on startup. */ -class SyncAccumulator { +export class SyncAccumulator { /** * @param {Object} opts * @param {Number=} opts.maxTimelineEntries The ideal maximum number of @@ -502,7 +502,7 @@ class SyncAccumulator { // since we're going back in time, we need to use the previous // state value else we'll break causality. We don't have the // complete previous state event, so we need to create one. - const prevStateEvent = utils.deepCopy(timelineEvent); + const prevStateEvent = deepCopy(timelineEvent); if (prevStateEvent.unsigned) { if (prevStateEvent.unsigned.prev_content) { prevStateEvent.content = prevStateEvent.unsigned.prev_content; @@ -554,5 +554,3 @@ function setState(eventMap, event) { } eventMap[event.type][event.state_key] = event; } - -module.exports = SyncAccumulator; diff --git a/src/sync.js b/src/sync.js index 80302ec1e..e575e58d4 100644 --- a/src/sync.js +++ b/src/sync.js @@ -2,6 +2,7 @@ Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 Vector Creations Ltd Copyright 2018 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,15 +26,15 @@ limitations under the License. * an alternative syncing API, we may want to have a proper syncing interface * for HTTP and WS at some point. */ -const User = require("./models/user"); -const Room = require("./models/room"); -const Group = require('./models/group'); -const utils = require("./utils"); -const Filter = require("./filter"); -const EventTimeline = require("./models/event-timeline"); -const PushProcessor = require("./pushprocessor"); -import logger from './logger'; +import {User} from "./models/user"; +import {Room} from "./models/room"; +import {Group} from "./models/group"; +import * as utils from "./utils"; +import {Filter} from "./filter"; +import {EventTimeline} from "./models/event-timeline"; +import {PushProcessor} from "./pushprocessor"; +import {logger} from './logger'; import {InvalidStoreError} from './errors'; const DEBUG = true; @@ -78,7 +79,7 @@ function debuglog(...params) { * @param {Boolean=} opts.disablePresence True to perform syncing without automatically * updating presence. */ -function SyncApi(client, opts) { +export function SyncApi(client, opts) { this.client = client; opts = opts || {}; opts.initialSyncLimit = ( @@ -1697,5 +1698,3 @@ function createNewUser(client, userId) { return user; } -/** */ -module.exports = SyncApi; diff --git a/src/timeline-window.js b/src/timeline-window.js index 03e515c62..c6edbf561 100644 --- a/src/timeline-window.js +++ b/src/timeline-window.js @@ -1,5 +1,6 @@ /* Copyright 2016 OpenMarket Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -17,8 +18,8 @@ limitations under the License. /** @module timeline-window */ -const EventTimeline = require("./models/event-timeline"); -import logger from './logger'; +import {EventTimeline} from './models/event-timeline'; +import {logger} from './logger'; /** * @private @@ -66,7 +67,7 @@ const DEFAULT_PAGINATE_LOOP_LIMIT = 5; * * @constructor */ -function TimelineWindow(client, timelineSet, opts) { +export function TimelineWindow(client, timelineSet, opts) { opts = opts || {}; this._client = client; this._timelineSet = timelineSet; @@ -397,7 +398,7 @@ TimelineWindow.prototype.getEvents = function() { * @param {number} index * @private */ -function TimelineIndex(timeline, index) { +export function TimelineIndex(timeline, index) { this.timeline = timeline; // the indexes are relative to BaseIndex, so could well be negative. @@ -491,12 +492,3 @@ TimelineIndex.prototype.retreat = function(delta) { return this.advance(delta * -1) * -1; }; -/** - * The TimelineWindow class. - */ -module.exports.TimelineWindow = TimelineWindow; - -/** - * The TimelineIndex class. exported here for unit testing. - */ -module.exports.TimelineIndex = TimelineIndex; diff --git a/src/utils.js b/src/utils.js index e830a5daf..1b5798960 100644 --- a/src/utils.js +++ b/src/utils.js @@ -20,7 +20,7 @@ limitations under the License. * @module utils */ -const unhomoglyph = require('unhomoglyph'); +import unhomoglyph from 'unhomoglyph'; /** * Encode a dictionary of query parameters. @@ -28,7 +28,7 @@ const unhomoglyph = require('unhomoglyph'); * {"foo": "bar", "baz": "taz"} * @return {string} The encoded string e.g. foo=bar&baz=taz */ -module.exports.encodeParams = function(params) { +export function encodeParams(params) { let qs = ""; for (const key in params) { if (!params.hasOwnProperty(key)) { @@ -38,7 +38,7 @@ module.exports.encodeParams = function(params) { encodeURIComponent(params[key]); } return qs.substring(1); -}; +} /** * Encodes a URI according to a set of template variables. Variables will be @@ -48,7 +48,7 @@ module.exports.encodeParams = function(params) { * variables with. E.g. { "$bar": "baz" }. * @return {string} The result of replacing all template variables e.g. '/foo/baz'. */ -module.exports.encodeUri = function(pathTemplate, variables) { +export function encodeUri(pathTemplate, variables) { for (const key in variables) { if (!variables.hasOwnProperty(key)) { continue; @@ -58,7 +58,7 @@ module.exports.encodeUri = function(pathTemplate, variables) { ); } return pathTemplate; -}; +} /** * Applies a map function to the given array. @@ -67,13 +67,13 @@ module.exports.encodeUri = function(pathTemplate, variables) { * the array with the signature fn(element){...} * @return {Array} A new array with the results of the function. */ -module.exports.map = function(array, fn) { +export function map(array, fn) { const results = new Array(array.length); for (let i = 0; i < array.length; i++) { results[i] = fn(array[i]); } return results; -}; +} /** * Applies a filter function to the given array. @@ -83,7 +83,7 @@ module.exports.map = function(array, fn) { * looks like fn(element, index, array){...}. * @return {Array} A new array with the results of the function. */ -module.exports.filter = function(array, fn) { +export function filter(array, fn) { const results = []; for (let i = 0; i < array.length; i++) { if (fn(array[i], i, array)) { @@ -91,14 +91,14 @@ module.exports.filter = function(array, fn) { } } return results; -}; +} /** * Get the keys for an object. Same as Object.keys(). * @param {Object} obj The object to get the keys for. * @return {string[]} The keys of the object. */ -module.exports.keys = function(obj) { +export function keys(obj) { const keys = []; for (const key in obj) { if (!obj.hasOwnProperty(key)) { @@ -107,14 +107,14 @@ module.exports.keys = function(obj) { keys.push(key); } return keys; -}; +} /** * Get the values for an object. * @param {Object} obj The object to get the values for. * @return {Array<*>} The values of the object. */ -module.exports.values = function(obj) { +export function values(obj) { const values = []; for (const key in obj) { if (!obj.hasOwnProperty(key)) { @@ -123,7 +123,7 @@ module.exports.values = function(obj) { values.push(obj[key]); } return values; -}; +} /** * Invoke a function for each item in the array. @@ -131,11 +131,11 @@ module.exports.values = function(obj) { * @param {Function} fn The function to invoke for each element. Has the * function signature fn(element, index). */ -module.exports.forEach = function(array, fn) { +export function forEach(array, fn) { for (let i = 0; i < array.length; i++) { fn(array[i], i); } -}; +} /** * The findElement() method returns a value in the array, if an element in the array @@ -148,7 +148,7 @@ module.exports.forEach = function(array, fn) { * @return {*} The first value in the array which returns true for * the given function. */ -module.exports.findElement = function(array, fn, reverse) { +export function findElement(array, fn, reverse) { let i; if (reverse) { for (i = array.length - 1; i >= 0; i--) { @@ -163,7 +163,7 @@ module.exports.findElement = function(array, fn, reverse) { } } } -}; +} /** * The removeElement() method removes the first element in the array that @@ -175,7 +175,7 @@ module.exports.findElement = function(array, fn, reverse) { * @param {boolean} reverse True to search in reverse order. * @return {boolean} True if an element was removed. */ -module.exports.removeElement = function(array, fn, reverse) { +export function removeElement(array, fn, reverse) { let i; let removed; if (reverse) { @@ -196,26 +196,26 @@ module.exports.removeElement = function(array, fn, reverse) { } } return false; -}; +} /** * Checks if the given thing is a function. * @param {*} value The thing to check. * @return {boolean} True if it is a function. */ -module.exports.isFunction = function(value) { +export function isFunction(value) { return Object.prototype.toString.call(value) == "[object Function]"; -}; +} /** * Checks if the given thing is an array. * @param {*} value The thing to check. * @return {boolean} True if it is an array. */ -module.exports.isArray = function(value) { +export function isArray(value) { return Array.isArray ? Array.isArray(value) : Boolean(value && value.constructor === Array); -}; +} /** * Checks that the given object has the specified keys. @@ -223,13 +223,13 @@ module.exports.isArray = function(value) { * @param {string[]} keys The list of keys that 'obj' must have. * @throws If the object is missing keys. */ -module.exports.checkObjectHasKeys = function(obj, keys) { +export function checkObjectHasKeys(obj, keys) { for (let i = 0; i < keys.length; i++) { if (!obj.hasOwnProperty(keys[i])) { throw new Error("Missing required key: " + keys[i]); } } -}; +} /** * Checks that the given object has no extra keys other than the specified ones. @@ -237,7 +237,7 @@ module.exports.checkObjectHasKeys = function(obj, keys) { * @param {string[]} allowedKeys The list of allowed key names. * @throws If there are extra keys. */ -module.exports.checkObjectHasNoAdditionalKeys = function(obj, allowedKeys) { +export function checkObjectHasNoAdditionalKeys(obj, allowedKeys) { for (const key in obj) { if (!obj.hasOwnProperty(key)) { continue; @@ -246,7 +246,7 @@ module.exports.checkObjectHasNoAdditionalKeys = function(obj, allowedKeys) { throw new Error("Unknown key: " + key); } } -}; +} /** * Deep copy the given object. The object MUST NOT have circular references and @@ -254,9 +254,9 @@ module.exports.checkObjectHasNoAdditionalKeys = function(obj, allowedKeys) { * @param {Object} obj The object to deep copy. * @return {Object} A copy of the object without any references to the original. */ -module.exports.deepCopy = function(obj) { +export function deepCopy(obj) { return JSON.parse(JSON.stringify(obj)); -}; +} /** * Compare two objects for equality. The objects MUST NOT have circular references. @@ -266,7 +266,7 @@ module.exports.deepCopy = function(obj) { * * @return {boolean} true if the two objects are equal */ -const deepCompare = module.exports.deepCompare = function(x, y) { +export function deepCompare(x, y) { // Inspired by // http://stackoverflow.com/questions/1068834/object-comparison-in-javascript#1144249 @@ -342,7 +342,7 @@ const deepCompare = module.exports.deepCompare = function(x, y) { } /* jshint +W089 */ return true; -}; +} /** * Copy properties from one object to another. @@ -357,7 +357,7 @@ const deepCompare = module.exports.deepCompare = function(x, y) { * * @return {Object} target */ -module.exports.extend = function() { +export function extend() { const target = arguments[0] || {}; for (let i = 1; i < arguments.length; i++) { const source = arguments[i]; @@ -366,12 +366,12 @@ module.exports.extend = function() { } } return target; -}; +} /** * Run polyfills to add Array.map and Array.filter if they are missing. */ -module.exports.runPolyfills = function() { +export function runPolyfills() { // Array.prototype.filter // ======================================================== // SOURCE: @@ -562,7 +562,7 @@ module.exports.runPolyfills = function() { // 8. return undefined }; } -}; +} /** * Inherit the prototype methods from one constructor into another. This is a @@ -572,7 +572,7 @@ module.exports.runPolyfills = function() { * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ -module.exports.inherits = function(ctor, superCtor) { +export function inherits(ctor, superCtor) { // Add Object.create polyfill for IE8 // Source: // https://developer.mozilla.org/en-US/docs/Web/JavaScript @@ -654,7 +654,27 @@ module.exports.inherits = function(ctor, superCtor) { configurable: true, }, }); -}; +} + +/** + * Polyfills inheritance for prototypes by allowing different kinds of + * super types. Typically prototypes would use `SuperType.call(this, params)` + * though this doesn't always work in some environments - this function + * falls back to using `Object.assign()` to clone a constructed copy + * of the super type onto `thisArg`. + * @param {any} thisArg The child instance. Modified in place. + * @param {any} SuperType The type to act as a super instance + * @param {any} params Arguments to supply to the super type's constructor + */ +export function polyfillSuper(thisArg, SuperType, ...params) { + try { + SuperType.call(thisArg, ...params); + } catch (e) { + // fall back to Object.assign to just clone the thing + const fakeSuper = new SuperType(...params); + Object.assign(thisArg, fakeSuper); + } +} /** * Returns whether the given value is a finite number without type-coercion @@ -662,9 +682,9 @@ module.exports.inherits = function(ctor, superCtor) { * @param {*} value the value to test * @return {boolean} whether or not value is a finite number without type-coercion */ -module.exports.isNumber = function(value) { +export function isNumber(value) { return typeof value === 'number' && isFinite(value); -}; +} /** * Removes zero width chars, diacritics and whitespace from the string @@ -672,17 +692,16 @@ module.exports.isNumber = function(value) { * @param {string} str the string to remove hidden characters from * @return {string} a string with the hidden characters removed */ -module.exports.removeHiddenChars = function(str) { +export function removeHiddenChars(str) { return unhomoglyph(str.normalize('NFD').replace(removeHiddenCharsRegex, '')); -}; +} const removeHiddenCharsRegex = /[\u200B-\u200D\u0300-\u036f\uFEFF\s]/g; -function escapeRegExp(string) { +export function escapeRegExp(string) { return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); } -module.exports.escapeRegExp = escapeRegExp; -module.exports.globToRegexp = function(glob, extended) { +export function globToRegexp(glob, extended) { extended = typeof(extended) === 'boolean' ? extended : true; // From // https://github.com/matrix-org/synapse/blob/abbee6b29be80a77e05730707602f3bbfc3f38cb/synapse/push/__init__.py#L132 @@ -699,27 +718,29 @@ module.exports.globToRegexp = function(glob, extended) { }); } return pat; -}; +} -module.exports.ensureNoTrailingSlash = function(url) { +export function ensureNoTrailingSlash(url) { if (url && url.endsWith("/")) { return url.substr(0, url.length - 1); } else { return url; } -}; +} // Returns a promise which resolves with a given value after the given number of ms -module.exports.sleep = (ms, value) => new Promise((resolve => { - setTimeout(resolve, ms, value); -})); +export function sleep(ms, value) { + return new Promise((resolve => { + setTimeout(resolve, ms, value); + })); +} -module.exports.isNullOrUndefined = function(val) { +export function isNullOrUndefined(val) { return val === null || val === undefined; -}; +} // Returns a Deferred -module.exports.defer = () => { +export function defer() { let resolve; let reject; @@ -729,14 +750,14 @@ module.exports.defer = () => { }); return {resolve, reject, promise}; -}; +} -module.exports.promiseMapSeries = async (promises, fn) => { +export async function promiseMapSeries(promises, fn) { for (const o of await promises) { await fn(await o); } -}; +} -module.exports.promiseTry = (fn) => { +export function promiseTry(fn) { return new Promise((resolve) => resolve(fn())); -}; +} diff --git a/src/webrtc/call.js b/src/webrtc/call.js index f5819c746..ee9a671ac 100644 --- a/src/webrtc/call.js +++ b/src/webrtc/call.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2017 New Vector Ltd +Copyright 2019 The Matrix.org Foundation C.I.C. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -19,9 +20,11 @@ limitations under the License. * This is an internal module. See {@link createNewMatrixCall} for the public API. * @module webrtc/call */ -const utils = require("../utils"); -const EventEmitter = require("events").EventEmitter; -import logger from '../logger'; + +import {logger} from '../logger'; +import {EventEmitter} from "events"; +import * as utils from "../utils"; + const DEBUG = true; // set true to enable console logging. // events: hangup, error(err), replaced(call), state(state, oldState) @@ -53,7 +56,7 @@ const DEBUG = true; // set true to enable console logging. * @param {Array} opts.turnServers Optional. A list of TURN servers. * @param {MatrixClient} opts.client The Matrix Client instance to send events to. */ -function MatrixCall(opts) { +export function MatrixCall(opts) { this.roomId = opts.roomId; this.client = opts.client; this.webRtc = opts.webRtc; @@ -1304,9 +1307,6 @@ const forAllTracksOnStream = function(s, f) { forAllAudioTracksOnStream(s, f); }; -/** The MatrixCall class. */ -module.exports.MatrixCall = MatrixCall; - let audioOutput; let audioInput; let videoInput; @@ -1316,21 +1316,21 @@ let videoInput; * @param {string=} deviceId the identifier for the device * undefined treated as unset */ -module.exports.setAudioOutput = function(deviceId) { audioOutput = deviceId; }; +export function setAudioOutput(deviceId) { audioOutput = deviceId; } /** * Set an audio input device to use for MatrixCalls * @function * @param {string=} deviceId the identifier for the device * undefined treated as unset */ -module.exports.setAudioInput = function(deviceId) { audioInput = deviceId; }; +export function setAudioInput(deviceId) { audioInput = deviceId; } /** * Set a video input device to use for MatrixCalls * @function * @param {string=} deviceId the identifier for the device * undefined treated as unset */ -module.exports.setVideoInput = function(deviceId) { videoInput = deviceId; }; +export function setVideoInput(deviceId) { videoInput = deviceId; } /** * Create a new Matrix call for the browser. @@ -1342,7 +1342,7 @@ module.exports.setVideoInput = function(deviceId) { videoInput = deviceId; }; * since it's only possible to set this option on outbound calls. * @return {MatrixCall} the call or null if the browser doesn't support calling. */ -module.exports.createNewMatrixCall = function(client, roomId, options) { +export function createNewMatrixCall(client, roomId, options) { const w = global.window; const doc = global.document; if (!w || !doc) { @@ -1417,4 +1417,4 @@ module.exports.createNewMatrixCall = function(client, roomId, options) { forceTURN: client._forceTURN || optionsForceTURN, }; return new MatrixCall(opts); -}; +}