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

Merge branch 'feed' into feed-audio

This commit is contained in:
Šimon Brandner
2021-03-17 16:16:33 +01:00
10 changed files with 146 additions and 59 deletions

View File

@@ -1,3 +1,58 @@
Changes in [9.9.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v9.9.0) (2021-03-15)
================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v9.9.0-rc.1...v9.9.0)
* No changes since rc.1
Changes in [9.9.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v9.9.0-rc.1) (2021-03-10)
==========================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v9.8.0...v9.9.0-rc.1)
* Remove detailed Olm session logging
[\#1638](https://github.com/matrix-org/matrix-js-sdk/pull/1638)
* Add space summary suggested only param
[\#1637](https://github.com/matrix-org/matrix-js-sdk/pull/1637)
* Check TURN servers periodically, and at start of calls
[\#1634](https://github.com/matrix-org/matrix-js-sdk/pull/1634)
* Support sending invite reasons
[\#1624](https://github.com/matrix-org/matrix-js-sdk/pull/1624)
* Bump elliptic from 6.5.3 to 6.5.4
[\#1636](https://github.com/matrix-org/matrix-js-sdk/pull/1636)
* Add a function to get a room's MXC URI
[\#1635](https://github.com/matrix-org/matrix-js-sdk/pull/1635)
* Stop streams if the call has ended
[\#1633](https://github.com/matrix-org/matrix-js-sdk/pull/1633)
* Remove export keyword from global.d.ts
[\#1631](https://github.com/matrix-org/matrix-js-sdk/pull/1631)
* Fix IndexedDB store creation example
[\#1445](https://github.com/matrix-org/matrix-js-sdk/pull/1445)
* An attempt to cleanup how constraints are handled in calls
[\#1613](https://github.com/matrix-org/matrix-js-sdk/pull/1613)
* Extract display name patterns to constants
[\#1628](https://github.com/matrix-org/matrix-js-sdk/pull/1628)
* Bump pug-code-gen from 2.0.2 to 2.0.3
[\#1630](https://github.com/matrix-org/matrix-js-sdk/pull/1630)
* Avoid deadlocks when ensuring Olm sessions for devices
[\#1627](https://github.com/matrix-org/matrix-js-sdk/pull/1627)
* Filter out edits from other senders in history
[\#1626](https://github.com/matrix-org/matrix-js-sdk/pull/1626)
* Fix ContentHelpers export
[\#1618](https://github.com/matrix-org/matrix-js-sdk/pull/1618)
* Add logging to in progress Olm sessions
[\#1621](https://github.com/matrix-org/matrix-js-sdk/pull/1621)
* Don't ignore ICE candidates received before offer/answer
[\#1623](https://github.com/matrix-org/matrix-js-sdk/pull/1623)
* Better handling of send failures on VoIP events
[\#1622](https://github.com/matrix-org/matrix-js-sdk/pull/1622)
* Log when turn creds expire
[\#1620](https://github.com/matrix-org/matrix-js-sdk/pull/1620)
* Initial Spaces [MSC1772] support
[\#1563](https://github.com/matrix-org/matrix-js-sdk/pull/1563)
* Add logging to crypto store transactions
[\#1617](https://github.com/matrix-org/matrix-js-sdk/pull/1617)
* Room helper for getting type and checking if it is a space room
[\#1610](https://github.com/matrix-org/matrix-js-sdk/pull/1610)
Changes in [9.8.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v9.8.0) (2021-03-01)
================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v9.8.0-rc.1...v9.8.0)

View File

@@ -1,6 +1,6 @@
{
"name": "matrix-js-sdk",
"version": "9.8.0",
"version": "9.9.0",
"description": "Matrix Client-Server SDK for Javascript",
"scripts": {
"prepublishOnly": "yarn build",

View File

@@ -1518,6 +1518,21 @@ MatrixBaseApis.prototype.getDevices = function() {
);
};
/**
* Gets specific device details for the logged-in user
* @param {string} device_id device to query
* @return {Promise} Resolves: result object
* @return {module:http-api.MatrixError} Rejects: with an error response.
*/
MatrixBaseApis.prototype.getDevice = function(device_id) {
const path = utils.encodeUri("/devices/$device_id", {
$device_id: device_id,
});
return this._http.authedRequest(
undefined, 'GET', path, undefined, undefined,
);
};
/**
* Update the given device
*
@@ -2378,18 +2393,27 @@ MatrixBaseApis.prototype.reportEvent = function(roomId, eventId, score, reason)
* Fetches or paginates a summary of a space as defined by MSC2946
* @param {string} roomId The ID of the space-room to use as the root of the summary.
* @param {number?} maxRoomsPerSpace The maximum number of rooms to return per subspace.
* @param {boolean?} suggestedOnly Whether to only return rooms with suggested=true.
* @param {boolean?} autoJoinOnly Whether to only return rooms with auto_join=true.
* @param {number?} limit The maximum number of rooms to return in total.
* @param {string?} batch The opaque token to paginate a previous summary request.
* @returns {Promise} the response, with next_batch, rooms, events fields.
*/
MatrixBaseApis.prototype.getSpaceSummary = function(roomId, maxRoomsPerSpace, autoJoinOnly, limit, batch) {
MatrixBaseApis.prototype.getSpaceSummary = function(
roomId,
maxRoomsPerSpace,
suggestedOnly,
autoJoinOnly,
limit,
batch,
) {
const path = utils.encodeUri("/rooms/$roomId/spaces", {
$roomId: roomId,
});
return this._http.authedRequest(undefined, "POST", path, null, {
max_rooms_per_space: maxRoomsPerSpace,
suggested_only: suggestedOnly,
auto_join_only: autoJoinOnly,
limit,
batch,

View File

@@ -500,19 +500,8 @@ MatrixClient.prototype.rehydrateDevice = async function() {
return;
}
let getDeviceResult;
try {
getDeviceResult = await this._http.authedRequest(
undefined,
"GET",
"/dehydrated_device",
undefined, undefined,
{
prefix: "/_matrix/client/unstable/org.matrix.msc2697.v2",
},
);
} catch (e) {
logger.info("could not get dehydrated device", e.toString());
const getDeviceResult = this.getDehydratedDevice();
if (!getDeviceResult) {
return;
}
@@ -574,6 +563,27 @@ MatrixClient.prototype.rehydrateDevice = async function() {
}
};
/**
* Get the current dehydrated device, if any
* @return {Promise} A promise of an object containing the dehydrated device
*/
MatrixClient.prototype.getDehydratedDevice = async function() {
try {
return await this._http.authedRequest(
undefined,
"GET",
"/dehydrated_device",
undefined, undefined,
{
prefix: "/_matrix/client/unstable/org.matrix.msc2697.v2",
},
);
} catch (e) {
logger.info("could not get dehydrated device", e.toString());
return;
}
};
/**
* Set the dehydration key. This will also periodically dehydrate devices to
* the server.

View File

@@ -213,9 +213,8 @@ export async function ensureOlmSessionsForDevices(
// synchronous operation, as otherwise it is possible to have deadlocks
// where multiple tasks wait indefinitely on another task to update some set
// of common devices.
for (const [userId, devices] of Object.entries(devicesByUser)) {
for (const [, devices] of Object.entries(devicesByUser)) {
for (const deviceInfo of devices) {
const deviceId = deviceInfo.deviceId;
const key = deviceInfo.getIdentityKey();
if (key === olmDevice.deviceCurve25519Key) {
@@ -224,15 +223,12 @@ export async function ensureOlmSessionsForDevices(
continue;
}
const forWhom = `for ${key} (${userId}:${deviceId})`;
if (!olmDevice._sessionsInProgress[key]) {
// pre-emptively mark the session as in-progress to avoid race
// conditions. If we find that we already have a session, then
// we'll resolve
log.debug(`Marking Olm session in progress ${forWhom}`);
olmDevice._sessionsInProgress[key] = new Promise(resolve => {
resolveSession[key] = (...args) => {
log.debug(`Resolved Olm session in progress ${forWhom}`);
delete olmDevice._sessionsInProgress[key];
resolve(...args);
};
@@ -266,11 +262,9 @@ export async function ensureOlmSessionsForDevices(
}
const forWhom = `for ${key} (${userId}:${deviceId})`;
log.debug(`Ensuring Olm session ${forWhom}`);
const sessionId = await olmDevice.getSessionIdForDevice(
key, resolveSession[key], log,
);
log.debug(`Got Olm session ${sessionId} ${forWhom}`);
if (sessionId !== null && resolveSession[key]) {
// we found a session, but we had marked the session as
// in-progress, so resolve it now, which will unmark it and
@@ -299,18 +293,6 @@ export async function ensureOlmSessionsForDevices(
const oneTimeKeyAlgorithm = "signed_curve25519";
let res;
let taskDetail = `one-time keys for ${devicesWithoutSession.length} devices`;
// If your homeserver takes a nap here and never replies, this process
// would hang indefinitely. While that's easily fixed by setting a
// timeout on this request, let's first log whether that's the root
// cause we're seeing in practice.
// See also https://github.com/vector-im/element-web/issues/16194
let otkTimeoutLogger;
// XXX: Perhaps there should be a default timeout?
if (otkTimeout) {
otkTimeoutLogger = setTimeout(() => {
log.error(`Homeserver never replied while claiming ${taskDetail}`);
}, otkTimeout);
}
try {
log.debug(`Claiming ${taskDetail}`);
res = await baseApis.claimOneTimeKeys(
@@ -323,8 +305,6 @@ export async function ensureOlmSessionsForDevices(
}
log.log(`Failed to claim ${taskDetail}`, e, devicesWithoutSession);
throw e;
} finally {
clearTimeout(otkTimeoutLogger);
}
if (failedServers && "failures" in res) {

View File

@@ -20,6 +20,7 @@ import {logger} from '../../logger';
import * as utils from "../../utils";
export const VERSION = 9;
const PROFILE_TRANSACTIONS = false;
/**
* Implementation of a CryptoStore which is backed by an existing
@@ -759,13 +760,18 @@ export class Backend {
}
doTxn(mode, stores, func, log = logger) {
let startTime;
let description;
if (PROFILE_TRANSACTIONS) {
const txnId = this._nextTxnId++;
const startTime = Date.now();
const description = `${mode} crypto store transaction ${txnId} in ${stores}`;
startTime = Date.now();
description = `${mode} crypto store transaction ${txnId} in ${stores}`;
log.debug(`Starting ${description}`);
}
const txn = this._db.transaction(stores, mode);
const promise = promiseifyTxn(txn);
const result = func(txn);
if (PROFILE_TRANSACTIONS) {
promise.then(() => {
const elapsedTime = Date.now() - startTime;
log.debug(`Finished ${description}, took ${elapsedTime} ms`);
@@ -773,6 +779,7 @@ export class Backend {
const elapsedTime = Date.now() - startTime;
log.error(`Failed ${description}, took ${elapsedTime} ms`);
});
}
return promise.then(() => {
return result;
});

View File

@@ -179,7 +179,9 @@ export class ToDeviceChannel {
const isAcceptingEvent = type === START_TYPE || type === READY_TYPE;
// the request has picked a ready or start event, tell the other devices about it
if (isAcceptingEvent && !wasStarted && isStarted && this._deviceId) {
const nonChosenDevices = this._devices.filter(d => d !== this._deviceId);
const nonChosenDevices = this._devices.filter(
d => d !== this._deviceId && d !== this._client.getDeviceId(),
);
if (nonChosenDevices.length) {
const message = this.completeContent({
code: "m.accepted",

View File

@@ -271,10 +271,10 @@ MatrixHttpApi.prototype = {
xhr.timeout_timer = callbacks.setTimeout(timeout_fn, 30000);
xhr.onreadystatechange = function() {
let resp;
switch (xhr.readyState) {
case global.XMLHttpRequest.DONE:
callbacks.clearTimeout(xhr.timeout_timer);
var resp;
try {
if (xhr.status === 0) {
throw new AbortError();

View File

@@ -479,6 +479,7 @@ export class MatrixCall extends EventEmitter {
this.chooseOpponent(event);
try {
await this.peerConn.setRemoteDescription(invite.offer);
await this.addBufferedIceCandidates();
} catch (e) {
logger.debug("Failed to set remote description", e);
this.terminate(CallParty.Local, CallErrorCode.SetRemoteDescription, false);
@@ -883,7 +884,7 @@ export class MatrixCall extends EventEmitter {
private gotLocalIceCandidate = (event: RTCPeerConnectionIceEvent) => {
if (event.candidate) {
logger.debug(
"Got local ICE " + event.candidate.sdpMid + " candidate: " +
"Call " + this.callId + " got local ICE " + event.candidate.sdpMid + " candidate: " +
event.candidate.candidate,
);
@@ -917,7 +918,7 @@ export class MatrixCall extends EventEmitter {
}
};
onRemoteIceCandidatesReceived(ev: MatrixEvent) {
async onRemoteIceCandidatesReceived(ev: MatrixEvent) {
if (this.callHasEnded()) {
//debuglog("Ignoring remote ICE candidate because call has ended");
return;
@@ -949,7 +950,7 @@ export class MatrixCall extends EventEmitter {
return;
}
this.addIceCandidates(cands);
await this.addIceCandidates(cands);
}
/**
@@ -957,7 +958,10 @@ export class MatrixCall extends EventEmitter {
* @param {Object} msg
*/
async onAnswerReceived(event: MatrixEvent) {
logger.debug(`Got answer for call ID ${this.callId} from party ID ${event.getContent().party_id}`);
if (this.callHasEnded()) {
logger.debug(`Ignoring answer because call ID ${this.callId} has ended`);
return;
}
@@ -970,6 +974,7 @@ export class MatrixCall extends EventEmitter {
}
this.chooseOpponent(event);
await this.addBufferedIceCandidates();
this.setState(CallState.Connecting);
@@ -1549,6 +1554,8 @@ export class MatrixCall extends EventEmitter {
// I choo-choo-choose you
const msg = ev.getContent();
logger.debug(`Choosing party ID ${msg.party_id} for call ID ${this.callId}`);
this.opponentVersion = msg.version;
if (this.opponentVersion === 0) {
// set to null to indicate that we've chosen an opponent, but because
@@ -1562,30 +1569,32 @@ export class MatrixCall extends EventEmitter {
}
this.opponentCaps = msg.capabilities || {};
this.opponentMember = ev.sender;
}
private async addBufferedIceCandidates() {
const bufferedCands = this.remoteCandidateBuffer.get(this.opponentPartyId);
if (bufferedCands) {
logger.info(`Adding ${bufferedCands.length} buffered candidates for opponent ${this.opponentPartyId}`);
this.addIceCandidates(bufferedCands);
await this.addIceCandidates(bufferedCands);
}
this.remoteCandidateBuffer = null;
}
private addIceCandidates(cands: RTCIceCandidate[]) {
private async addIceCandidates(cands: RTCIceCandidate[]) {
for (const cand of cands) {
if (
(cand.sdpMid === null || cand.sdpMid === undefined) &&
(cand.sdpMLineIndex === null || cand.sdpMLineIndex === undefined)
) {
logger.debug("Ignoring remote ICE candidate with no sdpMid or sdpMLineIndex");
return;
continue;
}
logger.debug("Got remote ICE " + cand.sdpMid + " candidate: " + cand.candidate);
logger.debug("Call " + this.callId + " got remote ICE " + cand.sdpMid + " candidate: " + cand.candidate);
try {
this.peerConn.addIceCandidate(cand);
await this.peerConn.addIceCandidate(cand);
} catch (err) {
if (!this.ignoreOffer) {
logger.info("Failed to add remore ICE candidate", err);
logger.info("Failed to add remote ICE candidate", err);
}
}
}