Compare commits

..

36 Commits

Author SHA1 Message Date
David Baker c6b500bc09 v0.10.6 2018-07-09 13:06:07 +01:00
David Baker c3972015c7 Prepare changelog for v0.10.6 2018-07-09 13:06:06 +01:00
David Baker 3c18c57857 v0.10.6-rc.1 2018-07-06 15:40:55 +01:00
David Baker f562a06707 Prepare changelog for v0.10.6-rc.1 2018-07-06 15:40:54 +01:00
David Baker c4fe15400c Merge pull request #665 from matrix-org/luke/feature-expose-decryption-error-2
Expose event decryption error via Event.decrypted event
2018-07-05 11:02:26 +01:00
David Baker 6e3e8f7310 Merge pull request #663 from matrix-org/luke/feature-decryption-error-codes
Add decryption error codes to base.DecryptionError
2018-07-05 11:00:33 +01:00
Luke Barnard fadb4d9219 Send OLM_UNKNOWN_MESSAGE_INDEX when possible 2018-07-04 15:58:45 +01:00
Luke Barnard b63149b36a Fix error code for Olm group message decryption 2018-07-04 14:33:02 +01:00
Luke Barnard 79f92abcfa Add jsdoc for Event.decrypted error 2018-07-04 14:28:15 +01:00
Luke Barnard 0137fb468b Expose event decryption error via Event.decrypted event 2018-07-04 13:56:03 +01:00
Luke Barnard 70ef8760cc Remove spurious console.dir 2018-07-04 11:56:02 +01:00
Luke Barnard c74d2d831b Add decryption error codes to base.DecryptionError
These should roughly follow https://github.com/matrix-org/matrix-ios-sdk/blob/9732cf593206a10d2b60cd01151a759c88c1e9a2/MatrixSDK/Crypto/Algorithms/MXDecryptionResult.h#L21-L39
2018-07-04 11:54:06 +01:00
David Baker 0415f821eb v0.10.5 2018-06-29 11:32:23 +01:00
David Baker 779fe35255 Prepare changelog for v0.10.5 2018-06-29 11:32:22 +01:00
David Baker 11382d2cd7 v0.10.5-rc.1 2018-06-21 10:01:05 +01:00
David Baker ef31131a5d Prepare changelog for v0.10.5-rc.1 2018-06-21 10:01:05 +01:00
David Baker 76feabe32b Merge pull request #659 from matrix-org/t3chguy/media_fixes
fix auth header and filename=undefined
2018-06-18 13:46:59 +01:00
Michael Telatynski 7fe3e2f90a invert argument to make it positive without breaking backwards compat
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-06-18 12:27:25 +01:00
Michael Telatynski c0b2151929 allow omitting filename from upload entirely
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-06-15 18:25:20 +01:00
Michael Telatynski 5e3b1bf6b0 use Authorization header in media/v1/upload if enabled, instead of query
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-06-15 09:57:30 +01:00
Michael Telatynski fdf4523c2a export the Group model class (#656)
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-06-14 13:52:13 +01:00
David Baker c6cf76f345 Merge branch 'master' into develop 2018-06-12 14:13:15 +01:00
David Baker f16e544691 v0.10.4 2018-06-12 14:11:07 +01:00
David Baker df101217fc Prepare changelog for v0.10.4 2018-06-12 14:11:07 +01:00
David Baker 5d90dc16cc Merge pull request #650 from matrix-org/t3chguy/audio_output
allow setting the output device for webrtc calls
2018-06-08 15:57:25 +01:00
David Baker bbfc1a1cd6 Merge pull request #596 from t3chguy/t3chguy/fix-docs
arguments true and false are actually invalid
2018-06-08 15:21:23 +01:00
Michael Telatynski b7208c12ac Merge pull request #643 from matrix-org/t3chguy/content-type-bugfix
fix typo where `headers` was not being used and thus sent wrong content-type
2018-06-08 12:29:35 +01:00
Michael Telatynski eaa2fdec44 Merge pull request #642 from matrix-org/t3chguy/doc_fixes
fix some documentation typos
2018-06-08 12:17:48 +01:00
David Baker 7099adfe79 v0.10.4-rc.1 2018-06-06 15:40:02 +01:00
David Baker cb17a2bcb0 Prepare changelog for v0.10.4-rc.1 2018-06-06 15:40:01 +01:00
Michael Telatynski 172044a1cb check whether notif level is undefined, because 0 is falsey (#651)
* check whether notif level is undefined, because `0` is falsey and it failed

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* improve number check for all m.room.power_levels related stuffs

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-05-29 12:11:29 +01:00
Michael Telatynski 4b203b6b63 allow setting the output device for webrtc calls
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-05-26 16:44:27 +01:00
Michael Telatynski 1bf1ce7070 fix typo where headers was not being used and thus sent wrong mime
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-04-30 06:56:43 +01:00
Michael Telatynski 260e7b529f fix some documentation typos
Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
2018-04-15 23:31:33 +01:00
Michael Telatynski b027089fc1 use constants 2018-04-15 22:16:25 +01:00
Michael Telatynski 95d582ccee arguments true and false are actually invalid 2018-01-19 23:00:34 +00:00
15 changed files with 163 additions and 22 deletions
+49
View File
@@ -1,3 +1,52 @@
Changes in [0.10.6](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.10.6) (2018-07-09)
==================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.10.6-rc.1...v0.10.6)
* No changes since rc.1
Changes in [0.10.6-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.10.6-rc.1) (2018-07-06)
============================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.10.5...v0.10.6-rc.1)
* Expose event decryption error via Event.decrypted event
[\#665](https://github.com/matrix-org/matrix-js-sdk/pull/665)
* Add decryption error codes to base.DecryptionError
[\#663](https://github.com/matrix-org/matrix-js-sdk/pull/663)
Changes in [0.10.5](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.10.5) (2018-06-29)
==================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.10.5-rc.1...v0.10.5)
* No changes since rc.1
Changes in [0.10.5-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.10.5-rc.1) (2018-06-21)
============================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.10.4...v0.10.5-rc.1)
* fix auth header and filename=undefined
[\#659](https://github.com/matrix-org/matrix-js-sdk/pull/659)
* allow setting the output device for webrtc calls
[\#650](https://github.com/matrix-org/matrix-js-sdk/pull/650)
* arguments true and false are actually invalid
[\#596](https://github.com/matrix-org/matrix-js-sdk/pull/596)
* fix typo where `headers` was not being used and thus sent wrong content-type
[\#643](https://github.com/matrix-org/matrix-js-sdk/pull/643)
* fix some documentation typos
[\#642](https://github.com/matrix-org/matrix-js-sdk/pull/642)
Changes in [0.10.4](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.10.4) (2018-06-12)
==================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.10.4-rc.1...v0.10.4)
* No changes since rc.1
Changes in [0.10.4-rc.1](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.10.4-rc.1) (2018-06-06)
============================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.10.3...v0.10.4-rc.1)
* check whether notif level is undefined, because `0` is falsey
[\#651](https://github.com/matrix-org/matrix-js-sdk/pull/651)
Changes in [0.10.3](https://github.com/matrix-org/matrix-js-sdk/releases/tag/v0.10.3) (2018-05-25)
==================================================================================================
[Full Changelog](https://github.com/matrix-org/matrix-js-sdk/compare/v0.10.3-rc.1...v0.10.3)
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "matrix-js-sdk",
"version": "0.10.3",
"version": "0.10.6",
"description": "Matrix Client-Server SDK for Javascript",
"main": "index.js",
"scripts": {
+4
View File
@@ -1071,6 +1071,10 @@ MatrixBaseApis.prototype.searchUserDirectory = function(opts) {
* @param {string=} opts.name Name to give the file on the server. Defaults
* to <tt>file.name</tt>.
*
* @param {boolean=} opts.includeFilename if false will not send the filename,
* e.g for encrypted file uploads where filename leaks are undesirable.
* Defaults to true.
*
* @param {string=} opts.type Content-type for the upload. Defaults to
* <tt>file.type</tt>, or <tt>applicaton/octet-stream</tt>.
*
+2 -2
View File
@@ -627,7 +627,7 @@ MatrixClient.prototype.isEventSenderVerified = async function(event) {
/**
* Cancel a room key request for this event if one is ongoing and resend the
* request.
* @param {MatrxEvent} event event of which to cancel and resend the room
* @param {MatrixEvent} event event of which to cancel and resend the room
* key request.
*/
MatrixClient.prototype.cancelAndResendEventRoomKeyRequest = function(event) {
@@ -721,7 +721,7 @@ MatrixClient.prototype.getGroup = function(groupId) {
/**
* Retrieve all known groups.
* @return {Groups[]} A list of groups, or an empty list if there is no data store.
* @return {Group[]} A list of groups, or an empty list if there is no data store.
*/
MatrixClient.prototype.getGroups = function() {
return this.store.getGroups();
+2 -1
View File
@@ -176,8 +176,9 @@ export {DecryptionAlgorithm}; // https://github.com/jsdoc3/jsdoc/issues/1272
* @extends Error
*/
class DecryptionError extends Error {
constructor(msg, details) {
constructor(code, msg, details) {
super(msg);
this.code = code;
this.name = 'DecryptionError';
this.detailedString = _detailedStringForDecryptionError(this, details);
}
+12 -1
View File
@@ -618,7 +618,10 @@ MegolmDecryption.prototype.decryptEvent = async function(event) {
if (!content.sender_key || !content.session_id ||
!content.ciphertext
) {
throw new base.DecryptionError("Missing fields in input");
throw new base.DecryptionError(
"MEGOLM_MISSING_FIELDS",
"Missing fields in input",
);
}
// we add the event to the pending list *before* we start decryption.
@@ -635,10 +638,16 @@ MegolmDecryption.prototype.decryptEvent = async function(event) {
event.getId(), event.getTs(),
);
} catch (e) {
let errorCode = "OLM_DECRYPT_GROUP_MESSAGE_ERROR";
if (e.message === 'OLM.UNKNOWN_MESSAGE_INDEX') {
this._requestKeysForEvent(event);
errorCode = 'OLM_UNKNOWN_MESSAGE_INDEX';
}
throw new base.DecryptionError(
errorCode,
e.toString(), {
session: content.sender_key + '|' + content.session_id,
},
@@ -655,6 +664,7 @@ MegolmDecryption.prototype.decryptEvent = async function(event) {
// scheduled, so we needn't send out the request here.)
this._requestKeysForEvent(event);
throw new base.DecryptionError(
"MEGOLM_UNKNOWN_INBOUND_SESSION_ID",
"The sender's device has not sent us the keys for this message.",
{
session: content.sender_key + '|' + content.session_id,
@@ -673,6 +683,7 @@ MegolmDecryption.prototype.decryptEvent = async function(event) {
// room, so neither the sender nor a MITM can lie about the room_id).
if (payload.room_id !== event.getRoomId()) {
throw new base.DecryptionError(
"MEGOLM_BAD_ROOM",
"Message intended for room " + payload.room_id,
);
}
+13 -2
View File
@@ -168,11 +168,17 @@ OlmDecryption.prototype.decryptEvent = async function(event) {
const ciphertext = content.ciphertext;
if (!ciphertext) {
throw new base.DecryptionError("Missing ciphertext");
throw new base.DecryptionError(
"OLM_MISSING_CIPHERTEXT",
"Missing ciphertext",
);
}
if (!(this._olmDevice.deviceCurve25519Key in ciphertext)) {
throw new base.DecryptionError("Not included in recipients");
throw new base.DecryptionError(
"OLM_NOT_INCLUDED_IN_RECIPIENTS",
"Not included in recipients",
);
}
const message = ciphertext[this._olmDevice.deviceCurve25519Key];
let payloadString;
@@ -181,6 +187,7 @@ OlmDecryption.prototype.decryptEvent = async function(event) {
payloadString = await this._decryptMessage(deviceKey, message);
} catch (e) {
throw new base.DecryptionError(
"OLM_BAD_ENCRYPTED_MESSAGE",
"Bad Encrypted Message", {
sender: deviceKey,
err: e,
@@ -194,12 +201,14 @@ OlmDecryption.prototype.decryptEvent = async function(event) {
// https://github.com/vector-im/vector-web/issues/2483
if (payload.recipient != this._userId) {
throw new base.DecryptionError(
"OLM_BAD_RECIPIENT",
"Message was intented for " + payload.recipient,
);
}
if (payload.recipient_keys.ed25519 != this._olmDevice.deviceEd25519Key) {
throw new base.DecryptionError(
"OLM_BAD_RECIPIENT_KEY",
"Message not intended for this device", {
intended: payload.recipient_keys.ed25519,
our_key: this._olmDevice.deviceEd25519Key,
@@ -213,6 +222,7 @@ OlmDecryption.prototype.decryptEvent = async function(event) {
// which is checked elsewhere).
if (payload.sender != event.getSender()) {
throw new base.DecryptionError(
"OLM_FORWARDED_MESSAGE",
"Message forwarded from " + payload.sender, {
reported_sender: event.getSender(),
},
@@ -222,6 +232,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(
"OLM_BAD_ROOM",
"Message intended for room " + payload.room_id, {
reported_room: event.room_id,
},
+1
View File
@@ -1275,6 +1275,7 @@ Crypto.prototype._getRoomDecryptor = function(roomId, algorithm) {
const AlgClass = algorithms.DECRYPTION_CLASSES[algorithm];
if (!AlgClass) {
throw new algorithms.DecryptionError(
'UNKNOWN_ENCRYPTION_ALGORITHM',
'Unknown encryption algorithm "' + algorithm + '".',
);
}
+31 -6
View File
@@ -118,6 +118,10 @@ module.exports.MatrixHttpApi.prototype = {
* @param {string=} opts.name Name to give the file on the server. Defaults
* to <tt>file.name</tt>.
*
* @param {boolean=} opts.includeFilename if false will not send the filename,
* e.g for encrypted file uploads where filename leaks are undesirable.
* Defaults to true.
*
* @param {string=} opts.type Content-type for the upload. Defaults to
* <tt>file.type</tt>, or <tt>applicaton/octet-stream</tt>.
*
@@ -152,6 +156,9 @@ module.exports.MatrixHttpApi.prototype = {
opts = {};
}
// default opts.includeFilename to true (ignoring falsey values)
const includeFilename = opts.includeFilename !== false;
// if the file doesn't have a mime type, use a default since
// the HS errors if we don't supply one.
const contentType = opts.type || file.type || 'application/octet-stream';
@@ -272,10 +279,26 @@ module.exports.MatrixHttpApi.prototype = {
}
});
let url = this.opts.baseUrl + "/_matrix/media/v1/upload";
url += "?access_token=" + encodeURIComponent(this.opts.accessToken);
url += "&filename=" + encodeURIComponent(fileName);
const queryArgs = [];
if (includeFilename && fileName) {
queryArgs.push("filename=" + encodeURIComponent(fileName));
}
if (!this.useAuthorizationHeader) {
queryArgs.push("access_token="
+ encodeURIComponent(this.opts.accessToken));
}
if (queryArgs.length > 0) {
url += "?" + queryArgs.join("&");
}
xhr.open("POST", url);
if (this.useAuthorizationHeader) {
xhr.setRequestHeader("Authorization", "Bearer " + this.opts.accessToken);
}
xhr.setRequestHeader("Content-Type", contentType);
xhr.send(body);
promise = defer.promise;
@@ -283,9 +306,11 @@ module.exports.MatrixHttpApi.prototype = {
// dirty hack (as per _request) to allow the upload to be cancelled.
promise.abort = xhr.abort.bind(xhr);
} else {
const queryParams = {
filename: fileName,
};
const queryParams = {};
if (includeFilename && fileName) {
queryParams.filename = fileName;
}
promise = this.authedRequest(
opts.callback, "POST", "/upload", queryParams, body, {
@@ -730,7 +755,7 @@ module.exports.MatrixHttpApi.prototype = {
body: data,
json: false,
timeout: localTimeoutMs,
headers: opts.headers || {},
headers: headers || {},
_matrix_opts: this.opts,
},
function(err, response, body) {
+9
View File
@@ -38,6 +38,8 @@ module.exports.MatrixError = require("./http-api").MatrixError;
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. */
@@ -81,6 +83,13 @@ module.exports.IndexedDBCryptoStore =
module.exports.createNewMatrixCall = require("./webrtc/call").createNewMatrixCall;
/**
* Set an 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 an audio input device to use for MatrixCalls
* @function
+9 -1
View File
@@ -404,6 +404,7 @@ utils.extend(module.exports.MatrixEvent.prototype, {
this._retryDecryption = false;
let res;
let err;
try {
if (!crypto) {
res = this._badEncryptedMessage("Encryption not enabled");
@@ -422,6 +423,8 @@ utils.extend(module.exports.MatrixEvent.prototype, {
return;
}
err = e;
// see if we have a retry queued.
//
// NB: make sure to keep this check in the same tick of the
@@ -467,6 +470,9 @@ utils.extend(module.exports.MatrixEvent.prototype, {
this._decryptionPromise = null;
this._retryDecryption = false;
this._setClearData(res);
this.emit("Event.decrypted", this, err);
return;
}
},
@@ -503,7 +509,6 @@ utils.extend(module.exports.MatrixEvent.prototype, {
decryptionResult.claimedEd25519Key || null;
this._forwardingCurve25519KeyChain =
decryptionResult.forwardingCurve25519KeyChain || [];
this.emit("Event.decrypted", this);
},
/**
@@ -708,4 +713,7 @@ const _REDACT_KEEP_CONTENT_MAP = {
*
* @param {module:models/event.MatrixEvent} event
* The matrix event which has been decrypted
* @param {module:crypto/algorithms/base.DecryptionError?} err
* The error that occured during decryption, or `undefined` if no
* error occured.
*/
+5 -5
View File
@@ -329,7 +329,7 @@ RoomState.prototype._hasSufficientPowerLevelFor = function(action, powerLevel) {
}
let requiredLevel = 50;
if (powerLevels[action] !== undefined) {
if (utils.isNumber(powerLevels[action])) {
requiredLevel = powerLevels[action];
}
@@ -417,18 +417,18 @@ RoomState.prototype._maySendEventOfType = function(eventType, userId, state) {
power_levels = power_levels_event.getContent();
events_levels = power_levels.events || {};
if (power_levels.state_default !== undefined) {
if (utils.isNumber(power_levels.state_default)) {
state_default = power_levels.state_default;
} else {
state_default = 50;
}
if (power_levels.events_default !== undefined) {
if (utils.isNumber(power_levels.events_default)) {
events_default = power_levels.events_default;
}
}
let required_level = state ? state_default : events_default;
if (events_levels[eventType] !== undefined) {
if (utils.isNumber(events_levels[eventType])) {
required_level = events_levels[eventType];
}
return member.powerLevel >= required_level;
@@ -455,7 +455,7 @@ RoomState.prototype.mayTriggerNotifOfType = function(notifLevelKey, userId) {
powerLevelsEvent &&
powerLevelsEvent.getContent() &&
powerLevelsEvent.getContent().notifications &&
powerLevelsEvent.getContent().notifications[notifLevelKey]
utils.isNumber(powerLevelsEvent.getContent().notifications[notifLevelKey])
) {
notifLevel = powerLevelsEvent.getContent().notifications[notifLevelKey];
}
+2 -2
View File
@@ -94,10 +94,10 @@ function synthesizeReceipt(userId, event, receiptType) {
* event type and the values are the events.
* @prop {RoomState} oldState The state of the room at the time of the oldest
* event in the live timeline. Present for backwards compatibility -
* prefer getLiveTimeline().getState(true).
* prefer getLiveTimeline().getState(EventTimeline.BACKWARDS).
* @prop {RoomState} currentState The state of the room at the time of the
* newest event in the timeline. Present for backwards compatibility -
* prefer getLiveTimeline().getState(false).
* prefer getLiveTimeline().getState(EventTimeline.FORWARDS).
* @prop {RoomSummary} summary The room summary.
* @prop {*} storageToken A token which a data store can use to remember
* the state of the room.
+10
View File
@@ -652,3 +652,13 @@ module.exports.inherits = function(ctor, superCtor) {
},
});
};
/**
* Returns whether the given value is a finite number without type-coercion
*
* @param {*} value the value to test
* @return {boolean} whether or not value is a finite number without type-coercion
*/
module.exports.isNumber = function(value) {
return typeof value === 'number' && isFinite(value);
};
+13 -1
View File
@@ -1121,9 +1121,13 @@ const _tryPlayRemoteStream = function(self) {
}
};
const _tryPlayRemoteAudioStream = function(self) {
const _tryPlayRemoteAudioStream = async function(self) {
if (self.getRemoteAudioElement() && self.remoteAStream) {
const player = self.getRemoteAudioElement();
// if audioOutput is non-default:
if (audioOutput) await player.setSinkId(audioOutput);
player.autoplay = true;
self.assignElement(player, self.remoteAStream, "remoteAudio");
setTimeout(function() {
@@ -1317,8 +1321,16 @@ const forAllTracksOnStream = function(s, f) {
/** The MatrixCall class. */
module.exports.MatrixCall = MatrixCall;
let audioOutput;
let audioInput;
let videoInput;
/**
* Set an audio output device to use for MatrixCalls
* @function
* @param {string=} deviceId the identifier for the device
* undefined treated as unset
*/
module.exports.setAudioOutput = function(deviceId) { audioOutput = deviceId; };
/**
* Set an audio input device to use for MatrixCalls
* @function