You've already forked matrix-js-sdk
mirror of
https://github.com/matrix-org/matrix-js-sdk.git
synced 2025-11-26 17:03:12 +03:00
Merge branch 'develop' into fix-screen-sharing
This commit is contained in:
35
CHANGELOG.md
35
CHANGELOG.md
@@ -1,3 +1,38 @@
|
|||||||
|
Changes in [9.5.0](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v9.5.0) (2021-01-18)
|
||||||
|
================================================================================================
|
||||||
|
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v9.5.0-rc.1...v9.5.0)
|
||||||
|
|
||||||
|
* No changes since rc.1
|
||||||
|
|
||||||
|
Changes in [9.5.0-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v9.5.0-rc.1) (2021-01-13)
|
||||||
|
==========================================================================================================
|
||||||
|
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v9.4.1...v9.5.0-rc.1)
|
||||||
|
|
||||||
|
* Don't log if no WebRTC
|
||||||
|
[\#1574](https://github.com/matrix-org/matrix-js-sdk/pull/1574)
|
||||||
|
* Add _unstable_getSharedRooms
|
||||||
|
[\#1417](https://github.com/matrix-org/matrix-js-sdk/pull/1417)
|
||||||
|
* Bump node-notifier from 8.0.0 to 8.0.1
|
||||||
|
[\#1568](https://github.com/matrix-org/matrix-js-sdk/pull/1568)
|
||||||
|
* Ignore party ID if opponent is v0
|
||||||
|
[\#1567](https://github.com/matrix-org/matrix-js-sdk/pull/1567)
|
||||||
|
* Basic call transfer initiation support
|
||||||
|
[\#1566](https://github.com/matrix-org/matrix-js-sdk/pull/1566)
|
||||||
|
* Room version 6 is now a thing
|
||||||
|
[\#1572](https://github.com/matrix-org/matrix-js-sdk/pull/1572)
|
||||||
|
* Store keys with same index but better trust level
|
||||||
|
[\#1571](https://github.com/matrix-org/matrix-js-sdk/pull/1571)
|
||||||
|
* Use TypeScript source for development, swap to build during release
|
||||||
|
[\#1561](https://github.com/matrix-org/matrix-js-sdk/pull/1561)
|
||||||
|
* Revert "Ignore party ID if opponent is v0"
|
||||||
|
[\#1565](https://github.com/matrix-org/matrix-js-sdk/pull/1565)
|
||||||
|
* Basic call transfer initiation support
|
||||||
|
[\#1558](https://github.com/matrix-org/matrix-js-sdk/pull/1558)
|
||||||
|
* Ignore party ID if opponent is v0
|
||||||
|
[\#1559](https://github.com/matrix-org/matrix-js-sdk/pull/1559)
|
||||||
|
* Honour a call reject event from another of our own devices
|
||||||
|
[\#1562](https://github.com/matrix-org/matrix-js-sdk/pull/1562)
|
||||||
|
|
||||||
Changes in [9.4.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v9.4.1) (2020-12-21)
|
Changes in [9.4.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v9.4.1) (2020-12-21)
|
||||||
================================================================================================
|
================================================================================================
|
||||||
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v9.4.0...v9.4.1)
|
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v9.4.0...v9.4.1)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "matrix-js-sdk",
|
"name": "matrix-js-sdk",
|
||||||
"version": "9.4.1",
|
"version": "9.5.0",
|
||||||
"description": "Matrix Client-Server SDK for Javascript",
|
"description": "Matrix Client-Server SDK for Javascript",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepublishOnly": "yarn build",
|
"prepublishOnly": "yarn build",
|
||||||
|
|||||||
@@ -521,4 +521,19 @@ describe("MatrixClient", function() {
|
|||||||
xit("should be able to peek into a room using peekInRoom", function(done) {
|
xit("should be able to peek into a room using peekInRoom", function(done) {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("getPresence", function() {
|
||||||
|
it("should send a presence HTTP GET", function() {
|
||||||
|
httpLookups = [{
|
||||||
|
method: "GET",
|
||||||
|
path: `/presence/${encodeURIComponent(userId)}/status`,
|
||||||
|
data: {
|
||||||
|
"presence": "unavailable",
|
||||||
|
"last_active_ago": 420845,
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
client.getPresence(userId);
|
||||||
|
expect(httpLookups.length).toEqual(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3841,6 +3841,19 @@ MatrixClient.prototype.setPresence = function(opts, callback) {
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} userId The user to get presence for
|
||||||
|
* @param {module:client.callback} callback Optional.
|
||||||
|
* @return {Promise} Resolves: The presence state for this user.
|
||||||
|
* @return {module:http-api.MatrixError} Rejects: with an error response.
|
||||||
|
*/
|
||||||
|
MatrixClient.prototype.getPresence = function(userId, callback) {
|
||||||
|
const path = utils.encodeUri("/presence/$userId/status", {
|
||||||
|
$userId: userId,
|
||||||
|
});
|
||||||
|
|
||||||
|
return this._http.authedRequest(callback, "GET", path, undefined, undefined);
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieve older messages from the given room and put them in the timeline.
|
* Retrieve older messages from the given room and put them in the timeline.
|
||||||
@@ -5425,6 +5438,11 @@ function checkTurnServers(client) {
|
|||||||
}
|
}
|
||||||
}, function(err) {
|
}, function(err) {
|
||||||
logger.error("Failed to get TURN URIs");
|
logger.error("Failed to get TURN URIs");
|
||||||
|
// If we get a 403, there's no point in looping forever.
|
||||||
|
if (err.httpStatus === 403) {
|
||||||
|
logger.info("TURN access unavailable for this account");
|
||||||
|
return;
|
||||||
|
}
|
||||||
client._checkTurnServersTimeoutID = setTimeout(function() {
|
client._checkTurnServersTimeoutID = setTimeout(function() {
|
||||||
checkTurnServers(client);
|
checkTurnServers(client);
|
||||||
}, 60000);
|
}, 60000);
|
||||||
|
|||||||
@@ -264,11 +264,14 @@ MegolmEncryption.prototype._ensureOutboundSession = async function(
|
|||||||
await Promise.all([
|
await Promise.all([
|
||||||
(async () => {
|
(async () => {
|
||||||
// share keys with devices that we already have a session for
|
// share keys with devices that we already have a session for
|
||||||
|
logger.debug(`Sharing keys with existing Olm sessions in ${this._roomId}`);
|
||||||
await this._shareKeyWithOlmSessions(
|
await this._shareKeyWithOlmSessions(
|
||||||
session, key, payload, olmSessions,
|
session, key, payload, olmSessions,
|
||||||
);
|
);
|
||||||
|
logger.debug(`Shared keys with existing Olm sessions in ${this._roomId}`);
|
||||||
})(),
|
})(),
|
||||||
(async () => {
|
(async () => {
|
||||||
|
logger.debug(`Sharing keys with new Olm sessions in ${this._roomId}`);
|
||||||
const errorDevices = [];
|
const errorDevices = [];
|
||||||
|
|
||||||
// meanwhile, establish olm sessions for devices that we don't
|
// meanwhile, establish olm sessions for devices that we don't
|
||||||
@@ -319,8 +322,10 @@ MegolmEncryption.prototype._ensureOutboundSession = async function(
|
|||||||
} else {
|
} else {
|
||||||
await this._notifyFailedOlmDevices(session, key, errorDevices);
|
await this._notifyFailedOlmDevices(session, key, errorDevices);
|
||||||
}
|
}
|
||||||
|
logger.debug(`Shared keys with new Olm sessions in ${this._roomId}`);
|
||||||
})(),
|
})(),
|
||||||
(async () => {
|
(async () => {
|
||||||
|
logger.debug(`Notifying blocked devices in ${this._roomId}`);
|
||||||
// also, notify blocked devices that they're blocked
|
// also, notify blocked devices that they're blocked
|
||||||
const blockedMap = {};
|
const blockedMap = {};
|
||||||
for (const [userId, userBlockedDevices] of Object.entries(blocked)) {
|
for (const [userId, userBlockedDevices] of Object.entries(blocked)) {
|
||||||
@@ -336,6 +341,7 @@ MegolmEncryption.prototype._ensureOutboundSession = async function(
|
|||||||
}
|
}
|
||||||
|
|
||||||
await this._notifyBlockedDevices(session, blockedMap);
|
await this._notifyBlockedDevices(session, blockedMap);
|
||||||
|
logger.debug(`Notified blocked devices in ${this._roomId}`);
|
||||||
})(),
|
})(),
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
@@ -348,6 +354,11 @@ MegolmEncryption.prototype._ensureOutboundSession = async function(
|
|||||||
// first wait for the previous share to complete
|
// first wait for the previous share to complete
|
||||||
const prom = this._setupPromise.then(prepareSession);
|
const prom = this._setupPromise.then(prepareSession);
|
||||||
|
|
||||||
|
// Ensure any failures are logged for debugging
|
||||||
|
prom.catch(e => {
|
||||||
|
logger.error(`Failed to ensure outbound session in ${this._roomId}`, e);
|
||||||
|
});
|
||||||
|
|
||||||
// _setupPromise resolves to `session` whether or not the share succeeds
|
// _setupPromise resolves to `session` whether or not the share succeeds
|
||||||
this._setupPromise = prom.then(returnSession, returnSession);
|
this._setupPromise = prom.then(returnSession, returnSession);
|
||||||
|
|
||||||
@@ -369,17 +380,11 @@ MegolmEncryption.prototype._prepareNewSession = async function() {
|
|||||||
key.key, {ed25519: this._olmDevice.deviceEd25519Key},
|
key.key, {ed25519: this._olmDevice.deviceEd25519Key},
|
||||||
);
|
);
|
||||||
|
|
||||||
if (this._crypto.backupInfo) {
|
|
||||||
// don't wait for it to complete
|
// don't wait for it to complete
|
||||||
this._crypto.backupGroupSession(
|
this._crypto.backupGroupSession(
|
||||||
this._roomId, this._olmDevice.deviceCurve25519Key, [],
|
this._roomId, this._olmDevice.deviceCurve25519Key, [],
|
||||||
sessionId, key.key,
|
sessionId, key.key,
|
||||||
).catch((e) => {
|
);
|
||||||
// This throws if the upload failed, but this is fine
|
|
||||||
// since it will have written it to the db and will retry.
|
|
||||||
logger.log("Failed to back up megolm session", e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return new OutboundSessionInfo(sessionId);
|
return new OutboundSessionInfo(sessionId);
|
||||||
};
|
};
|
||||||
@@ -846,12 +851,22 @@ MegolmEncryption.prototype.prepareToEncrypt = function(room) {
|
|||||||
// We're already preparing something, so don't do anything else.
|
// We're already preparing something, so don't do anything else.
|
||||||
// FIXME: check if we need to restart
|
// FIXME: check if we need to restart
|
||||||
// (https://github.com/matrix-org/matrix-js-sdk/issues/1255)
|
// (https://github.com/matrix-org/matrix-js-sdk/issues/1255)
|
||||||
|
const elapsedTime = Date.now() - this.encryptionPreparationMetadata.startTime;
|
||||||
|
logger.debug(
|
||||||
|
`Already started preparing to encrypt for ${this._roomId} ` +
|
||||||
|
`${elapsedTime} ms ago, skipping`,
|
||||||
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.debug(`Preparing to encrypt events for ${this._roomId}`);
|
logger.debug(`Preparing to encrypt events for ${this._roomId}`);
|
||||||
|
|
||||||
|
this.encryptionPreparationMetadata = {
|
||||||
|
startTime: Date.now(),
|
||||||
|
};
|
||||||
this.encryptionPreparation = (async () => {
|
this.encryptionPreparation = (async () => {
|
||||||
|
try {
|
||||||
|
logger.debug(`Getting devices in ${this._roomId}`);
|
||||||
const [devicesInRoom, blocked] = await this._getDevicesInRoom(room);
|
const [devicesInRoom, blocked] = await this._getDevicesInRoom(room);
|
||||||
|
|
||||||
if (this._crypto.getGlobalErrorOnUnknownDevices()) {
|
if (this._crypto.getGlobalErrorOnUnknownDevices()) {
|
||||||
@@ -861,9 +876,16 @@ MegolmEncryption.prototype.prepareToEncrypt = function(room) {
|
|||||||
this._removeUnknownDevices(devicesInRoom);
|
this._removeUnknownDevices(devicesInRoom);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger.debug(`Ensuring outbound session in ${this._roomId}`);
|
||||||
await this._ensureOutboundSession(devicesInRoom, blocked, true);
|
await this._ensureOutboundSession(devicesInRoom, blocked, true);
|
||||||
|
|
||||||
|
logger.debug(`Ready to encrypt events for ${this._roomId}`);
|
||||||
|
} catch (e) {
|
||||||
|
logger.error(`Failed to prepare to encrypt events for ${this._roomId}`, e);
|
||||||
|
} finally {
|
||||||
|
delete this.encryptionPreparationMetadata;
|
||||||
delete this.encryptionPreparation;
|
delete this.encryptionPreparation;
|
||||||
|
}
|
||||||
})();
|
})();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1347,18 +1369,12 @@ MegolmDecryption.prototype.onRoomKeyEvent = function(event) {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}).then(() => {
|
}).then(() => {
|
||||||
if (this._crypto.backupInfo) {
|
|
||||||
// don't wait for the keys to be backed up for the server
|
// don't wait for the keys to be backed up for the server
|
||||||
this._crypto.backupGroupSession(
|
this._crypto.backupGroupSession(
|
||||||
content.room_id, senderKey, forwardingKeyChain,
|
content.room_id, senderKey, forwardingKeyChain,
|
||||||
content.session_id, content.session_key, keysClaimed,
|
content.session_id, content.session_key, keysClaimed,
|
||||||
exportFormat,
|
exportFormat,
|
||||||
).catch((e) => {
|
);
|
||||||
// This throws if the upload failed, but this is fine
|
|
||||||
// since it will have written it to the db and will retry.
|
|
||||||
logger.log("Failed to back up megolm session", e);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
logger.error(`Error handling m.room_key_event: ${e}`);
|
logger.error(`Error handling m.room_key_event: ${e}`);
|
||||||
});
|
});
|
||||||
@@ -1564,7 +1580,7 @@ MegolmDecryption.prototype.importRoomKey = function(session, opts = {}) {
|
|||||||
true,
|
true,
|
||||||
opts.untrusted ? { untrusted: opts.untrusted } : {},
|
opts.untrusted ? { untrusted: opts.untrusted } : {},
|
||||||
).then(() => {
|
).then(() => {
|
||||||
if (this._crypto.backupInfo && opts.source !== "backup") {
|
if (opts.source !== "backup") {
|
||||||
// don't wait for it to complete
|
// don't wait for it to complete
|
||||||
this._crypto.backupGroupSession(
|
this._crypto.backupGroupSession(
|
||||||
session.room_id,
|
session.room_id,
|
||||||
|
|||||||
@@ -2884,18 +2884,18 @@ Crypto.prototype.backupGroupSession = async function(
|
|||||||
sessionId, sessionKey, keysClaimed,
|
sessionId, sessionKey, keysClaimed,
|
||||||
exportFormat,
|
exportFormat,
|
||||||
) {
|
) {
|
||||||
if (!this.backupInfo) {
|
|
||||||
throw new Error("Key backups are not enabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
await this._cryptoStore.markSessionsNeedingBackup([{
|
await this._cryptoStore.markSessionsNeedingBackup([{
|
||||||
senderKey: senderKey,
|
senderKey: senderKey,
|
||||||
sessionId: sessionId,
|
sessionId: sessionId,
|
||||||
}]);
|
}]);
|
||||||
|
|
||||||
|
if (this.backupInfo) {
|
||||||
// don't wait for this to complete: it will delay so
|
// don't wait for this to complete: it will delay so
|
||||||
// happens in the background
|
// happens in the background
|
||||||
this.scheduleKeyBackupSend();
|
this.scheduleKeyBackupSend();
|
||||||
|
}
|
||||||
|
// if this.backupInfo is not set, then the keys will be backed up when
|
||||||
|
// client.enableKeyBackup is called
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1136,8 +1136,21 @@ export class MatrixCall extends EventEmitter {
|
|||||||
await this.peerConn.setRemoteDescription(description);
|
await this.peerConn.setRemoteDescription(description);
|
||||||
|
|
||||||
if (description.type === 'offer') {
|
if (description.type === 'offer') {
|
||||||
|
// First we sent the direction of the tranciever to what we'd like it to be,
|
||||||
|
// irresepective of whether the other side has us on hold - so just whether we
|
||||||
|
// want the call to be on hold or not. This is necessary because in a few lines,
|
||||||
|
// we'll adjust the direction and unless we do this too, we'll never come off hold.
|
||||||
|
for (const tranceiver of this.peerConn.getTransceivers()) {
|
||||||
|
tranceiver.direction = this.isRemoteOnHold() ? 'inactive' : 'sendrecv';
|
||||||
|
}
|
||||||
const localDescription = await this.peerConn.createAnswer();
|
const localDescription = await this.peerConn.createAnswer();
|
||||||
await this.peerConn.setLocalDescription(localDescription);
|
await this.peerConn.setLocalDescription(localDescription);
|
||||||
|
// Now we've got our answer, set the direction to the outcome of the negotiation.
|
||||||
|
// We need to do this otherwise Firefox will notice that the direction is not the
|
||||||
|
// currentDirection and try to negotiate itself off hold again.
|
||||||
|
for (const tranceiver of this.peerConn.getTransceivers()) {
|
||||||
|
tranceiver.direction = tranceiver.currentDirection;
|
||||||
|
}
|
||||||
|
|
||||||
this.sendVoipEvent(EventType.CallNegotiate, {
|
this.sendVoipEvent(EventType.CallNegotiate, {
|
||||||
description: this.peerConn.localDescription,
|
description: this.peerConn.localDescription,
|
||||||
@@ -1281,7 +1294,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
return; // because ICE can still complete as we're ending the call
|
return; // because ICE can still complete as we're ending the call
|
||||||
}
|
}
|
||||||
logger.debug(
|
logger.debug(
|
||||||
"ICE connection state changed to: " + this.peerConn.iceConnectionState,
|
"Call ID " + this.callId + ": ICE connection state changed to: " + this.peerConn.iceConnectionState,
|
||||||
);
|
);
|
||||||
// ideally we'd consider the call to be connected when we get media but
|
// ideally we'd consider the call to be connected when we get media but
|
||||||
// chrome doesn't implement any of the 'onstarted' events yet
|
// chrome doesn't implement any of the 'onstarted' events yet
|
||||||
@@ -1399,7 +1412,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
onHangupReceived = (msg) => {
|
onHangupReceived = (msg) => {
|
||||||
logger.debug("Hangup received");
|
logger.debug("Hangup received for call ID " + + this.callId);
|
||||||
|
|
||||||
// party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen
|
// party ID must match (our chosen partner hanging up the call) or be undefined (we haven't chosen
|
||||||
// a partner yet but we're treating the hangup as a reject as per VoIP v0)
|
// a partner yet but we're treating the hangup as a reject as per VoIP v0)
|
||||||
@@ -1412,7 +1425,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onRejectReceived = (msg) => {
|
onRejectReceived = (msg) => {
|
||||||
logger.debug("Reject received");
|
logger.debug("Reject received for call ID " + this.callId);
|
||||||
|
|
||||||
// No need to check party_id for reject because if we'd received either
|
// No need to check party_id for reject because if we'd received either
|
||||||
// an answer or reject, we wouldn't be in state InviteSent
|
// an answer or reject, we wouldn't be in state InviteSent
|
||||||
@@ -1434,7 +1447,7 @@ export class MatrixCall extends EventEmitter {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onAnsweredElsewhere = (msg) => {
|
onAnsweredElsewhere = (msg) => {
|
||||||
logger.debug("Answered elsewhere");
|
logger.debug("Call ID " + this.callId + " answered elsewhere");
|
||||||
this.terminate(CallParty.Remote, CallErrorCode.AnsweredElsewhere, true);
|
this.terminate(CallParty.Remote, CallErrorCode.AnsweredElsewhere, true);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user