diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000000..1fbc4dccb7
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,6 @@
+language: node_js
+node_js:
+ - 6 # node v6, to match jenkins
+install:
+ - npm install
+ - (cd node_modules/matrix-react-sdk && npm run build)
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2103aad1e7..83d60f7d8a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,40 @@
+Changes in [0.7.5-r1](https://github.com/vector-im/vector-web/releases/tag/v0.7.5-r1) (2016-08-28)
+==================================================================================================
+[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.5...v0.7.5-r1)
+
+ * Correctly pin deps :(
+
+Changes in [0.7.5](https://github.com/vector-im/vector-web/releases/tag/v0.7.5) (2016-08-28)
+============================================================================================
+[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.4-r1...v0.7.5)
+
+ * re-add leave button in RoomSettings
+ * add /user URLs
+ * recognise matrix.to links and other vector links
+ * fix linkify dependency
+ * fix avatar clicking in MemberInfo
+ * fix RoomTagContextMenu so it works on historical rooms
+ * warn people to put their Matrix HS on a separate domain to Vector
+ * fix zalgos again
+ * Add .travis.yml
+ [\#2007](https://github.com/vector-im/vector-web/pull/2007)
+ * add fancy changelog dialog
+ [\#1972](https://github.com/vector-im/vector-web/pull/1972)
+ * Update autocomplete design
+ [\#1978](https://github.com/vector-im/vector-web/pull/1978)
+ * Update encryption info in README
+ [\#2001](https://github.com/vector-im/vector-web/pull/2001)
+ * Added event/info message avatars back in
+ [\#2000](https://github.com/vector-im/vector-web/pull/2000)
+ * Wmwragg/chat message presentation
+ [\#1987](https://github.com/vector-im/vector-web/pull/1987)
+ * Make the notification slider work
+ [\#1982](https://github.com/vector-im/vector-web/pull/1982)
+ * Use cpx to copy olm.js, and add watcher
+ [\#1966](https://github.com/vector-im/vector-web/pull/1966)
+ * Make up a device display name
+ [\#1959](https://github.com/vector-im/vector-web/pull/1959)
+
Changes in [0.7.4-r1](https://github.com/vector-im/vector-web/releases/tag/v0.7.4-r1) (2016-08-12)
==================================================================================================
[Full Changelog](https://github.com/vector-im/vector-web/compare/v0.7.4...v0.7.4-r1)
diff --git a/README.md b/README.md
index a940da64d2..aff57eb9d4 100644
--- a/README.md
+++ b/README.md
@@ -8,7 +8,7 @@ Getting Started
The easiest way to test Vector is to just use the hosted copy at https://vector.im/beta.
The develop branch is continuously deployed by Jenkins at https://vector.im/develop for
-those who like living dangerously.
+those who like living dangerously.
To host your own copy of Vector, the quickest bet is to use a pre-built released version
of Vector:
@@ -20,6 +20,19 @@ of Vector:
as desired. See below for details.
1. Enter the URL into your browser and log into vector!
+Important Security Note
+=======================
+
+We do not recommend running Vector from the same domain name as your Matrix
+homeserver. The reason is the risk of XSS (cross-site-scripting) vulnerabilities
+that could occur if someone caused Vector to load and render malicious user generated
+content from a Matrix API which then had trusted access to Vector (or other apps) due
+to sharing the same domain.
+
+We have put some coarse mitigations into place to try to protect against this situation,
+but it's still not good practice to do it in the first place.
+See https://github.com/vector-im/vector-web/issues/1977 for more details.
+
Building From Source
====================
@@ -55,7 +68,7 @@ You can configure the app by copying `vector/config.sample.json` to
for verifying third party identifiers like email addresses). If this is blank,
registering with an email address, adding an email address to your account,
or inviting users via email address will not work. Matrix identity servers are
- very simple web services which map third party identifiers (currently only email
+ very simple web services which map third party identifiers (currently only email
addresses) to matrix IDs: see http://matrix.org/docs/spec/identity_service/unstable.html
for more details. Currently the only public matrix identity servers are https://matrix.org
and https://vector.im. In future identity servers will be decentralised.
@@ -75,7 +88,9 @@ nativefier https://vector.im/beta/
```
krisa has a dedicated electron project at https://github.com/krisak/vector-electron-desktop
-(although you should swap out the 'vector' folder for the latest vector tarball you want to run)
+(although you should swap out the 'vector' folder for the latest vector tarball you want to run.
+Get a tarball from https://vector.im/packages or build your own - see Building From Source
+above).
There's also a (much) older electron distribution at https://github.com/stevenhammerton/vector-desktop
@@ -216,20 +231,13 @@ day-to-day use; it is experimental and should be considered only as a
proof-of-concept. See https://matrix.org/jira/browse/SPEC-162 for an overview
of the current progress.
-Vector is built with support for end-to-end encryption by default.
-
-To enable encryption for a room, type
-
-```
-/encrypt on
-```
-
-in the message bar in that room. Vector will then generate a set of keys, and
-encrypt all outgoing messages in that room. (Note that other people in that
-room will send messages in the clear unless they also `/encrypt on`.)
+To enable the (very experimental) support, check the 'End-to-End Encryption'
+box in the 'Labs' section of the user settings (note that the labs are disabled
+on http://vector.im/beta: you will need to use http://vector.im/develop or your
+own deployment of vector). The Room Settings dialog will then show an
+'Encryption' setting; rooms for which you are an administrator will offer you
+the option of enabling encryption. Any messages sent in that room will then be
+encrypted.
Note that historical encrypted messages cannot currently be decoded - history
is therefore lost when the page is reloaded.
-
-There is currently no visual indication of whether encryption is enabled for a
-room.
diff --git a/jenkins.sh b/jenkins.sh
index f60bec38b2..3a4ee0c704 100755
--- a/jenkins.sh
+++ b/jenkins.sh
@@ -4,12 +4,15 @@ set -e
export NVM_DIR="/home/jenkins/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
-nvm use 4
+nvm use 6
set -x
npm install
+# apparently npm 3.10.3 on node 6.4.0 doesn't upgrade #develop target with npm install unless explicitly asked.
+npm install matrix-react-sdk matrix-js-sdk
+
# we may be using a dev branch of react-sdk, in which case we need to build it
(cd node_modules/matrix-react-sdk && npm run build)
diff --git a/package.json b/package.json
index be87139b26..7f1e8d921d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "vector-web",
- "version": "0.7.4-r1",
+ "version": "0.7.5-r1",
"description": "Vector webapp",
"author": "matrix.org",
"repository": {
@@ -46,9 +46,9 @@
"gemini-scrollbar": "matrix-org/gemini-scrollbar#b302279",
"gfm.css": "^1.1.1",
"highlight.js": "^9.0.0",
- "linkifyjs": "^2.0.0-beta.4",
- "matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
- "matrix-react-sdk": "matrix-org/matrix-react-sdk#develop",
+ "linkifyjs": "2.0.0-beta.4",
+ "matrix-js-sdk": "0.5.6",
+ "matrix-react-sdk": "0.6.5",
"modernizr": "^3.1.0",
"q": "^1.4.1",
"react": "^15.2.1",
diff --git a/src/component-index.js b/src/component-index.js
index b4c73a4b0f..dfe549930a 100644
--- a/src/component-index.js
+++ b/src/component-index.js
@@ -37,6 +37,7 @@ module.exports.components['structures.ViewSource'] = require('./components/struc
module.exports.components['views.context_menus.MessageContextMenu'] = require('./components/views/context_menus/MessageContextMenu');
module.exports.components['views.context_menus.NotificationStateContextMenu'] = require('./components/views/context_menus/NotificationStateContextMenu');
module.exports.components['views.context_menus.RoomTagContextMenu'] = require('./components/views/context_menus/RoomTagContextMenu');
+module.exports.components['views.dialogs.ChangelogDialog'] = require('./components/views/dialogs/ChangelogDialog');
module.exports.components['views.elements.ImageView'] = require('./components/views/elements/ImageView');
module.exports.components['views.elements.Spinner'] = require('./components/views/elements/Spinner');
module.exports.components['views.globals.GuestWarningBar'] = require('./components/views/globals/GuestWarningBar');
diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js
index ca9376e1b4..4ca3dded9c 100644
--- a/src/components/structures/RightPanel.js
+++ b/src/components/structures/RightPanel.js
@@ -17,7 +17,8 @@ limitations under the License.
'use strict';
var React = require('react');
-var sdk = require('matrix-react-sdk')
+var sdk = require('matrix-react-sdk');
+var Matrix = require("matrix-js-sdk");
var dis = require('matrix-react-sdk/lib/dispatcher');
var MatrixClientPeg = require("matrix-react-sdk/lib/MatrixClientPeg");
var rate_limited_func = require('matrix-react-sdk/lib/ratelimitedfunc');
@@ -45,8 +46,17 @@ module.exports = React.createClass({
},
getInitialState: function() {
- return {
- phase : this.Phase.MemberList
+ if (this.props.userId) {
+ var member = new Matrix.RoomMember(null, this.props.userId);
+ return {
+ phase: this.Phase.MemberInfo,
+ member: member,
+ }
+ }
+ else {
+ return {
+ phase: this.Phase.MemberList
+ }
}
},
@@ -97,7 +107,7 @@ module.exports = React.createClass({
});
}
}
- if (payload.action === "view_room") {
+ else if (payload.action === "view_room") {
if (this.state.phase === this.Phase.MemberInfo) {
this.setState({
phase: this.Phase.MemberList
@@ -145,15 +155,15 @@ module.exports = React.createClass({
{ filesHighlight }
;
+ }
- if (!this.props.collapsed) {
- if(this.state.phase == this.Phase.MemberList) {
- panel =
- }
- else if(this.state.phase == this.Phase.MemberInfo) {
- var MemberInfo = sdk.getComponent('rooms.MemberInfo');
- panel =
- }
+ if (!this.props.collapsed) {
+ if(this.props.roomId && this.state.phase == this.Phase.MemberList) {
+ panel =
+ }
+ else if(this.state.phase == this.Phase.MemberInfo) {
+ var MemberInfo = sdk.getComponent('rooms.MemberInfo');
+ panel =
}
}
diff --git a/src/components/structures/RoomSubList.js b/src/components/structures/RoomSubList.js
index 4817218be4..4fd2618d6b 100644
--- a/src/components/structures/RoomSubList.js
+++ b/src/components/structures/RoomSubList.js
@@ -456,7 +456,7 @@ var RoomSubList = React.createClass({
// is run with historical room tag data, after that there should only be undefined
// in the list at a time anyway.
for (let i = 0; i < list.length; i++) {
- if (list[i].tags[self.props.tagName].order === undefined) {
+ if (list[i].tags[self.props.tagName] && list[i].tags[self.props.tagName].order === undefined) {
MatrixClientPeg.get().setRoomTag(list[i].roomId, self.props.tagName, {order: (order + 1.0) / 2.0}).finally(function() {
// Do any final stuff here
}).fail(function(err) {
diff --git a/src/components/views/context_menus/MessageContextMenu.js b/src/components/views/context_menus/MessageContextMenu.js
index 401c0c6cc0..737b7faa41 100644
--- a/src/components/views/context_menus/MessageContextMenu.js
+++ b/src/components/views/context_menus/MessageContextMenu.js
@@ -133,12 +133,11 @@ module.exports = React.createClass({
}
}
- // XXX: this should be https://matrix.to.
// XXX: if we use room ID, we should also include a server where the event can be found (other than in the domain of the event ID)
permalinkButton = (
);
diff --git a/src/components/views/context_menus/RoomTagContextMenu.js b/src/components/views/context_menus/RoomTagContextMenu.js
index 776f952272..3637a3a5ee 100644
--- a/src/components/views/context_menus/RoomTagContextMenu.js
+++ b/src/components/views/context_menus/RoomTagContextMenu.js
@@ -126,6 +126,25 @@ module.exports = React.createClass({
};
},
+ _onClickForget: function() {
+ // FIXME: duplicated with RoomSettings (and dead code in RoomView)
+ MatrixClientPeg.get().forget(this.props.room.roomId).done(function() {
+ dis.dispatch({ action: 'view_next_room' });
+ }, function(err) {
+ var errCode = err.errcode || "unknown error code";
+ var ErrorDialog = sdk.getComponent("dialogs.ErrorDialog");
+ Modal.createDialog(ErrorDialog, {
+ title: "Error",
+ description: `Failed to forget room (${errCode})`
+ });
+ });
+
+ // Close the context menu
+ if (this.props.onFinished) {
+ this.props.onFinished();
+ };
+ },
+
render: function() {
var myUserId = MatrixClientPeg.get().credentials.userId;
var myMember = this.props.room.getMember(myUserId);
@@ -148,6 +167,17 @@ module.exports = React.createClass({
'mx_RoomTagContextMenu_fieldDisabled': false,
});
+ if (myMember && myMember.membership === "leave") {
+ return (
+
+
+
+ Forget
+
+
+ );
+ }
+
return (
diff --git a/src/components/views/dialogs/ChangelogDialog.js b/src/components/views/dialogs/ChangelogDialog.js
new file mode 100644
index 0000000000..ea32a756a1
--- /dev/null
+++ b/src/components/views/dialogs/ChangelogDialog.js
@@ -0,0 +1,82 @@
+/*
+ Copyright 2016 Aviral Dasgupta
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+import React from 'react';
+import sdk from 'matrix-react-sdk';
+import request from 'browser-request';
+
+const REPOS = ['vector-im/vector-web', 'matrix-org/matrix-react-sdk', 'matrix-org/matrix-js-sdk'];
+
+export default class ChangelogDialog extends React.Component {
+ constructor(props) {
+ super(props);
+
+ this.state = {};
+ }
+
+ componentDidMount() {
+ const version = this.props.newVersion.split('-');
+ const version2 = this.props.version.split('-');
+ if(version == null || version2 == null) return;
+ for(let i=0; i {
+ if(body == null) return;
+ this.setState({[REPOS[i]]: JSON.parse(body).commits});
+ });
+ }
+ }
+
+ render() {
+ const Spinner = sdk.getComponent('views.elements.Spinner');
+ const QuestionDialog = sdk.getComponent('dialogs.QuestionDialog');
+
+ const logs = REPOS.map(repo => {
+ if (this.state[repo] == null) return ;
+ return (
+