Merge branch 'develop' of github.com:matrix-org/matrix-react-sdk into t3chguy/electron_call_sleep
This commit is contained in:
commit
edcfb77a6d
9 changed files with 410 additions and 132 deletions
|
@ -9,11 +9,16 @@ set -ev
|
|||
RIOT_WEB_DIR=riot-web
|
||||
REACT_SDK_DIR=`pwd`
|
||||
|
||||
git clone --depth=1 --branch develop https://github.com/vector-im/riot-web.git \
|
||||
curbranch="${TRAVIS_PULL_REQUEST_BRANCH:-$TRAVIS_BRANCH}"
|
||||
echo "Determined branch to be $curbranch"
|
||||
|
||||
git clone https://github.com/vector-im/riot-web.git \
|
||||
"$RIOT_WEB_DIR"
|
||||
|
||||
cd "$RIOT_WEB_DIR"
|
||||
|
||||
git checkout "$curbranch" || git checkout develop
|
||||
|
||||
mkdir node_modules
|
||||
npm install
|
||||
|
||||
|
|
151
CHANGELOG.md
151
CHANGELOG.md
|
@ -1,3 +1,154 @@
|
|||
Changes in [0.8.9](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.9) (2017-05-22)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.9-rc.1...v0.8.9)
|
||||
|
||||
* No changes
|
||||
|
||||
|
||||
Changes in [0.8.9-rc.1](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.9-rc.1) (2017-05-19)
|
||||
=============================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.8...v0.8.9-rc.1)
|
||||
|
||||
* Prevent an exception getting scroll node
|
||||
[\#902](https://github.com/matrix-org/matrix-react-sdk/pull/902)
|
||||
* Fix a few remaining snags with country dd
|
||||
[\#901](https://github.com/matrix-org/matrix-react-sdk/pull/901)
|
||||
* Add left_aligned class to CountryDropdown
|
||||
[\#900](https://github.com/matrix-org/matrix-react-sdk/pull/900)
|
||||
* Swap to new flag files (which are stored as GB.png)
|
||||
[\#899](https://github.com/matrix-org/matrix-react-sdk/pull/899)
|
||||
* Improve phone number country dropdown for registration and login (Act. 2,
|
||||
Return of the Prefix)
|
||||
[\#897](https://github.com/matrix-org/matrix-react-sdk/pull/897)
|
||||
* Support for pasting files into normal composer
|
||||
[\#892](https://github.com/matrix-org/matrix-react-sdk/pull/892)
|
||||
* tell guests they can't use filepanel until they register
|
||||
[\#887](https://github.com/matrix-org/matrix-react-sdk/pull/887)
|
||||
* Prevent reskindex -w from running when file names have not changed
|
||||
[\#888](https://github.com/matrix-org/matrix-react-sdk/pull/888)
|
||||
* I broke UserSettings for webpack-dev-server
|
||||
[\#884](https://github.com/matrix-org/matrix-react-sdk/pull/884)
|
||||
* various fixes to RoomHeader
|
||||
[\#880](https://github.com/matrix-org/matrix-react-sdk/pull/880)
|
||||
* remove /me whether or not it has a space after it
|
||||
[\#885](https://github.com/matrix-org/matrix-react-sdk/pull/885)
|
||||
* show error if we can't set a filter because no room
|
||||
[\#883](https://github.com/matrix-org/matrix-react-sdk/pull/883)
|
||||
* Fix RM not updating if RR event unpaginated
|
||||
[\#874](https://github.com/matrix-org/matrix-react-sdk/pull/874)
|
||||
* change roomsettings wording
|
||||
[\#878](https://github.com/matrix-org/matrix-react-sdk/pull/878)
|
||||
* make reskindex windows friendly
|
||||
[\#875](https://github.com/matrix-org/matrix-react-sdk/pull/875)
|
||||
* Fixes 2 issues with Dialog closing
|
||||
[\#867](https://github.com/matrix-org/matrix-react-sdk/pull/867)
|
||||
* Automatic Reskindex
|
||||
[\#871](https://github.com/matrix-org/matrix-react-sdk/pull/871)
|
||||
* Put room name in 'leave room' confirmation dialog
|
||||
[\#873](https://github.com/matrix-org/matrix-react-sdk/pull/873)
|
||||
* Fix this/self fail in LeftPanel
|
||||
[\#872](https://github.com/matrix-org/matrix-react-sdk/pull/872)
|
||||
* Don't show null URL previews
|
||||
[\#870](https://github.com/matrix-org/matrix-react-sdk/pull/870)
|
||||
* Fix keys for AddressSelector
|
||||
[\#869](https://github.com/matrix-org/matrix-react-sdk/pull/869)
|
||||
* Make left panel better for new users (mk II)
|
||||
[\#859](https://github.com/matrix-org/matrix-react-sdk/pull/859)
|
||||
* Explicitly save composer content onUnload
|
||||
[\#866](https://github.com/matrix-org/matrix-react-sdk/pull/866)
|
||||
* Warn on unload
|
||||
[\#851](https://github.com/matrix-org/matrix-react-sdk/pull/851)
|
||||
* Log deviceid at login
|
||||
[\#862](https://github.com/matrix-org/matrix-react-sdk/pull/862)
|
||||
* Guests can't send RR so no point trying
|
||||
[\#860](https://github.com/matrix-org/matrix-react-sdk/pull/860)
|
||||
* Remove babelcheck
|
||||
[\#861](https://github.com/matrix-org/matrix-react-sdk/pull/861)
|
||||
* T3chguy/settings versions improvements
|
||||
[\#857](https://github.com/matrix-org/matrix-react-sdk/pull/857)
|
||||
* Change max-len 90->120
|
||||
[\#852](https://github.com/matrix-org/matrix-react-sdk/pull/852)
|
||||
* Remove DM-guessing code
|
||||
[\#829](https://github.com/matrix-org/matrix-react-sdk/pull/829)
|
||||
* Fix jumping to an unread event when in MELS
|
||||
[\#855](https://github.com/matrix-org/matrix-react-sdk/pull/855)
|
||||
* Validate phone number on login
|
||||
[\#856](https://github.com/matrix-org/matrix-react-sdk/pull/856)
|
||||
* Failed to enable HTML5 Notifications Error Dialogs
|
||||
[\#827](https://github.com/matrix-org/matrix-react-sdk/pull/827)
|
||||
* Pin filesize ver to fix break upstream
|
||||
[\#854](https://github.com/matrix-org/matrix-react-sdk/pull/854)
|
||||
* Improve RoomDirectory Look & Feel
|
||||
[\#848](https://github.com/matrix-org/matrix-react-sdk/pull/848)
|
||||
* Only show jumpToReadMarker bar when RM !== RR
|
||||
[\#845](https://github.com/matrix-org/matrix-react-sdk/pull/845)
|
||||
* Allow MELS to have its own RM
|
||||
[\#846](https://github.com/matrix-org/matrix-react-sdk/pull/846)
|
||||
* Use document.onkeydown instead of onkeypress
|
||||
[\#844](https://github.com/matrix-org/matrix-react-sdk/pull/844)
|
||||
* (Room)?Avatar: Request 96x96 avatars on high DPI screens
|
||||
[\#808](https://github.com/matrix-org/matrix-react-sdk/pull/808)
|
||||
* Add mx_EventTile_emote class
|
||||
[\#842](https://github.com/matrix-org/matrix-react-sdk/pull/842)
|
||||
* Fix dialog reappearing after hitting Enter
|
||||
[\#841](https://github.com/matrix-org/matrix-react-sdk/pull/841)
|
||||
* Fix spinner that shows until the first sync
|
||||
[\#840](https://github.com/matrix-org/matrix-react-sdk/pull/840)
|
||||
* Show spinner until first sync has completed
|
||||
[\#839](https://github.com/matrix-org/matrix-react-sdk/pull/839)
|
||||
* Style fixes for LoggedInView
|
||||
[\#838](https://github.com/matrix-org/matrix-react-sdk/pull/838)
|
||||
* Fix specifying custom server for registration
|
||||
[\#834](https://github.com/matrix-org/matrix-react-sdk/pull/834)
|
||||
* Improve country dropdown UX and expose +prefix
|
||||
[\#833](https://github.com/matrix-org/matrix-react-sdk/pull/833)
|
||||
* Fix user settings store
|
||||
[\#836](https://github.com/matrix-org/matrix-react-sdk/pull/836)
|
||||
* show the room name in the UDE Dialog
|
||||
[\#832](https://github.com/matrix-org/matrix-react-sdk/pull/832)
|
||||
* summarise profile changes in MELS
|
||||
[\#826](https://github.com/matrix-org/matrix-react-sdk/pull/826)
|
||||
* Transform h1 and h2 tags to h3 tags
|
||||
[\#820](https://github.com/matrix-org/matrix-react-sdk/pull/820)
|
||||
* limit our keyboard shortcut modifiers correctly
|
||||
[\#825](https://github.com/matrix-org/matrix-react-sdk/pull/825)
|
||||
* Specify cross platform regexes and add olm to noParse
|
||||
[\#823](https://github.com/matrix-org/matrix-react-sdk/pull/823)
|
||||
* Remember element that was in focus before rendering dialog
|
||||
[\#822](https://github.com/matrix-org/matrix-react-sdk/pull/822)
|
||||
* move user settings outward and use built in read receipts disabling
|
||||
[\#824](https://github.com/matrix-org/matrix-react-sdk/pull/824)
|
||||
* File Download Consistency
|
||||
[\#802](https://github.com/matrix-org/matrix-react-sdk/pull/802)
|
||||
* Show Access Token under Advanced in Settings
|
||||
[\#806](https://github.com/matrix-org/matrix-react-sdk/pull/806)
|
||||
* Link tags/commit hashes in the UserSettings version section
|
||||
[\#810](https://github.com/matrix-org/matrix-react-sdk/pull/810)
|
||||
* On return to RoomView from auxPanel, send focus back to Composer
|
||||
[\#813](https://github.com/matrix-org/matrix-react-sdk/pull/813)
|
||||
* Change presence status labels to 'for' instead of 'ago'
|
||||
[\#817](https://github.com/matrix-org/matrix-react-sdk/pull/817)
|
||||
* Disable Scalar Integrations if urls passed to it are falsey
|
||||
[\#816](https://github.com/matrix-org/matrix-react-sdk/pull/816)
|
||||
* Add option to hide other people's read receipts.
|
||||
[\#818](https://github.com/matrix-org/matrix-react-sdk/pull/818)
|
||||
* Add option to not send typing notifications
|
||||
[\#819](https://github.com/matrix-org/matrix-react-sdk/pull/819)
|
||||
* Sync RM across instances of Riot
|
||||
[\#805](https://github.com/matrix-org/matrix-react-sdk/pull/805)
|
||||
* First iteration on improving login UI
|
||||
[\#811](https://github.com/matrix-org/matrix-react-sdk/pull/811)
|
||||
* focus on composer after jumping to bottom
|
||||
[\#809](https://github.com/matrix-org/matrix-react-sdk/pull/809)
|
||||
* Improve RoomList performance via side-stepping React
|
||||
[\#807](https://github.com/matrix-org/matrix-react-sdk/pull/807)
|
||||
* Don't show link preview when link is inside of a quote
|
||||
[\#762](https://github.com/matrix-org/matrix-react-sdk/pull/762)
|
||||
* Escape closes UserSettings
|
||||
[\#765](https://github.com/matrix-org/matrix-react-sdk/pull/765)
|
||||
* Implement user power-level changes in timeline
|
||||
[\#794](https://github.com/matrix-org/matrix-react-sdk/pull/794)
|
||||
|
||||
Changes in [0.8.8](https://github.com/matrix-org/matrix-react-sdk/releases/tag/v0.8.8) (2017-04-25)
|
||||
===================================================================================================
|
||||
[Full Changelog](https://github.com/matrix-org/matrix-react-sdk/compare/v0.8.8-rc.2...v0.8.8)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "matrix-react-sdk",
|
||||
"version": "0.8.8",
|
||||
"version": "0.8.9",
|
||||
"description": "SDK for matrix.org using React",
|
||||
"author": "matrix.org",
|
||||
"repository": {
|
||||
|
@ -63,7 +63,7 @@
|
|||
"isomorphic-fetch": "^2.2.1",
|
||||
"linkifyjs": "^2.1.3",
|
||||
"lodash": "^4.13.1",
|
||||
"matrix-js-sdk": "matrix-org/matrix-js-sdk#develop",
|
||||
"matrix-js-sdk": "0.7.8",
|
||||
"optimist": "^0.6.1",
|
||||
"q": "^1.4.1",
|
||||
"react": "^15.4.0",
|
||||
|
|
|
@ -14,9 +14,9 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
var MatrixClientPeg = require("./MatrixClientPeg");
|
||||
var dis = require("./dispatcher");
|
||||
var Tinter = require("./Tinter");
|
||||
import MatrixClientPeg from "./MatrixClientPeg";
|
||||
import dis from "./dispatcher";
|
||||
import Tinter from "./Tinter";
|
||||
import sdk from './index';
|
||||
import Modal from './Modal';
|
||||
|
||||
|
@ -45,19 +45,25 @@ class Command {
|
|||
}
|
||||
}
|
||||
|
||||
var reject = function(msg) {
|
||||
function reject(msg) {
|
||||
return {
|
||||
error: msg
|
||||
error: msg,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
var success = function(promise) {
|
||||
function success(promise) {
|
||||
return {
|
||||
promise: promise
|
||||
promise: promise,
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
var commands = {
|
||||
/* Disable the "unexpected this" error for these commands - all of the run
|
||||
* functions are called with `this` bound to the Command instance.
|
||||
*/
|
||||
|
||||
/* eslint-disable babel/no-invalid-this */
|
||||
|
||||
const commands = {
|
||||
ddg: new Command("ddg", "<query>", function(roomId, args) {
|
||||
const ErrorDialog = sdk.getComponent('dialogs.ErrorDialog');
|
||||
// TODO Don't explain this away, actually show a search UI here.
|
||||
|
@ -69,30 +75,30 @@ var commands = {
|
|||
}),
|
||||
|
||||
// Change your nickname
|
||||
nick: new Command("nick", "<display_name>", function(room_id, args) {
|
||||
nick: new Command("nick", "<display_name>", function(roomId, args) {
|
||||
if (args) {
|
||||
return success(
|
||||
MatrixClientPeg.get().setDisplayName(args)
|
||||
MatrixClientPeg.get().setDisplayName(args),
|
||||
);
|
||||
}
|
||||
return reject(this.getUsage());
|
||||
}),
|
||||
|
||||
// Changes the colorscheme of your current room
|
||||
tint: new Command("tint", "<color1> [<color2>]", function(room_id, args) {
|
||||
tint: new Command("tint", "<color1> [<color2>]", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}))( +(#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})))?$/);
|
||||
const matches = args.match(/^(#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}))( +(#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})))?$/);
|
||||
if (matches) {
|
||||
Tinter.tint(matches[1], matches[4]);
|
||||
var colorScheme = {};
|
||||
const colorScheme = {};
|
||||
colorScheme.primary_color = matches[1];
|
||||
if (matches[4]) {
|
||||
colorScheme.secondary_color = matches[4];
|
||||
}
|
||||
return success(
|
||||
MatrixClientPeg.get().setRoomAccountData(
|
||||
room_id, "org.matrix.room.color_scheme", colorScheme
|
||||
)
|
||||
roomId, "org.matrix.room.color_scheme", colorScheme,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -100,22 +106,22 @@ var commands = {
|
|||
}),
|
||||
|
||||
// Change the room topic
|
||||
topic: new Command("topic", "<topic>", function(room_id, args) {
|
||||
topic: new Command("topic", "<topic>", function(roomId, args) {
|
||||
if (args) {
|
||||
return success(
|
||||
MatrixClientPeg.get().setRoomTopic(room_id, args)
|
||||
MatrixClientPeg.get().setRoomTopic(roomId, args),
|
||||
);
|
||||
}
|
||||
return reject(this.getUsage());
|
||||
}),
|
||||
|
||||
// Invite a user
|
||||
invite: new Command("invite", "<userId>", function(room_id, args) {
|
||||
invite: new Command("invite", "<userId>", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+)$/);
|
||||
const matches = args.match(/^(\S+)$/);
|
||||
if (matches) {
|
||||
return success(
|
||||
MatrixClientPeg.get().invite(room_id, matches[1])
|
||||
MatrixClientPeg.get().invite(roomId, matches[1]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -123,21 +129,21 @@ var commands = {
|
|||
}),
|
||||
|
||||
// Join a room
|
||||
join: new Command("join", "#alias:domain", function(room_id, args) {
|
||||
join: new Command("join", "#alias:domain", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+)$/);
|
||||
const matches = args.match(/^(\S+)$/);
|
||||
if (matches) {
|
||||
var room_alias = matches[1];
|
||||
if (room_alias[0] !== '#') {
|
||||
let roomAlias = matches[1];
|
||||
if (roomAlias[0] !== '#') {
|
||||
return reject(this.getUsage());
|
||||
}
|
||||
if (!room_alias.match(/:/)) {
|
||||
room_alias += ':' + MatrixClientPeg.get().getDomain();
|
||||
if (!roomAlias.match(/:/)) {
|
||||
roomAlias += ':' + MatrixClientPeg.get().getDomain();
|
||||
}
|
||||
|
||||
dis.dispatch({
|
||||
action: 'view_room',
|
||||
room_alias: room_alias,
|
||||
roomAlias: roomAlias,
|
||||
auto_join: true,
|
||||
});
|
||||
|
||||
|
@ -147,29 +153,29 @@ var commands = {
|
|||
return reject(this.getUsage());
|
||||
}),
|
||||
|
||||
part: new Command("part", "[#alias:domain]", function(room_id, args) {
|
||||
var targetRoomId;
|
||||
part: new Command("part", "[#alias:domain]", function(roomId, args) {
|
||||
let targetRoomId;
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+)$/);
|
||||
const matches = args.match(/^(\S+)$/);
|
||||
if (matches) {
|
||||
var room_alias = matches[1];
|
||||
if (room_alias[0] !== '#') {
|
||||
let roomAlias = matches[1];
|
||||
if (roomAlias[0] !== '#') {
|
||||
return reject(this.getUsage());
|
||||
}
|
||||
if (!room_alias.match(/:/)) {
|
||||
room_alias += ':' + MatrixClientPeg.get().getDomain();
|
||||
if (!roomAlias.match(/:/)) {
|
||||
roomAlias += ':' + MatrixClientPeg.get().getDomain();
|
||||
}
|
||||
|
||||
// Try to find a room with this alias
|
||||
var rooms = MatrixClientPeg.get().getRooms();
|
||||
for (var i = 0; i < rooms.length; i++) {
|
||||
var aliasEvents = rooms[i].currentState.getStateEvents(
|
||||
"m.room.aliases"
|
||||
const rooms = MatrixClientPeg.get().getRooms();
|
||||
for (let i = 0; i < rooms.length; i++) {
|
||||
const aliasEvents = rooms[i].currentState.getStateEvents(
|
||||
"m.room.aliases",
|
||||
);
|
||||
for (var j = 0; j < aliasEvents.length; j++) {
|
||||
var aliases = aliasEvents[j].getContent().aliases || [];
|
||||
for (var k = 0; k < aliases.length; k++) {
|
||||
if (aliases[k] === room_alias) {
|
||||
for (let j = 0; j < aliasEvents.length; j++) {
|
||||
const aliases = aliasEvents[j].getContent().aliases || [];
|
||||
for (let k = 0; k < aliases.length; k++) {
|
||||
if (aliases[k] === roomAlias) {
|
||||
targetRoomId = rooms[i].roomId;
|
||||
break;
|
||||
}
|
||||
|
@ -178,27 +184,28 @@ var commands = {
|
|||
}
|
||||
if (targetRoomId) { break; }
|
||||
}
|
||||
}
|
||||
if (!targetRoomId) {
|
||||
return reject("Unrecognised room alias: " + room_alias);
|
||||
if (!targetRoomId) {
|
||||
return reject("Unrecognised room alias: " + roomAlias);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!targetRoomId) targetRoomId = room_id;
|
||||
if (!targetRoomId) targetRoomId = roomId;
|
||||
return success(
|
||||
MatrixClientPeg.get().leave(targetRoomId).then(
|
||||
function() {
|
||||
dis.dispatch({action: 'view_next_room'});
|
||||
})
|
||||
function() {
|
||||
dis.dispatch({action: 'view_next_room'});
|
||||
},
|
||||
),
|
||||
);
|
||||
}),
|
||||
|
||||
// Kick a user from the room with an optional reason
|
||||
kick: new Command("kick", "<userId> [<reason>]", function(room_id, args) {
|
||||
kick: new Command("kick", "<userId> [<reason>]", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+?)( +(.*))?$/);
|
||||
const matches = args.match(/^(\S+?)( +(.*))?$/);
|
||||
if (matches) {
|
||||
return success(
|
||||
MatrixClientPeg.get().kick(room_id, matches[1], matches[3])
|
||||
MatrixClientPeg.get().kick(roomId, matches[1], matches[3]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -206,12 +213,12 @@ var commands = {
|
|||
}),
|
||||
|
||||
// Ban a user from the room with an optional reason
|
||||
ban: new Command("ban", "<userId> [<reason>]", function(room_id, args) {
|
||||
ban: new Command("ban", "<userId> [<reason>]", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+?)( +(.*))?$/);
|
||||
const matches = args.match(/^(\S+?)( +(.*))?$/);
|
||||
if (matches) {
|
||||
return success(
|
||||
MatrixClientPeg.get().ban(room_id, matches[1], matches[3])
|
||||
MatrixClientPeg.get().ban(roomId, matches[1], matches[3]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -219,13 +226,13 @@ var commands = {
|
|||
}),
|
||||
|
||||
// Unban a user from the room
|
||||
unban: new Command("unban", "<userId>", function(room_id, args) {
|
||||
unban: new Command("unban", "<userId>", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+)$/);
|
||||
const matches = args.match(/^(\S+)$/);
|
||||
if (matches) {
|
||||
// Reset the user membership to "leave" to unban him
|
||||
return success(
|
||||
MatrixClientPeg.get().unban(room_id, matches[1])
|
||||
MatrixClientPeg.get().unban(roomId, matches[1]),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -233,27 +240,27 @@ var commands = {
|
|||
}),
|
||||
|
||||
// Define the power level of a user
|
||||
op: new Command("op", "<userId> [<power level>]", function(room_id, args) {
|
||||
op: new Command("op", "<userId> [<power level>]", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+?)( +(\d+))?$/);
|
||||
var powerLevel = 50; // default power level for op
|
||||
const matches = args.match(/^(\S+?)( +(\d+))?$/);
|
||||
let powerLevel = 50; // default power level for op
|
||||
if (matches) {
|
||||
var user_id = matches[1];
|
||||
const userId = matches[1];
|
||||
if (matches.length === 4 && undefined !== matches[3]) {
|
||||
powerLevel = parseInt(matches[3]);
|
||||
}
|
||||
if (powerLevel !== NaN) {
|
||||
var room = MatrixClientPeg.get().getRoom(room_id);
|
||||
if (!isNaN(powerLevel)) {
|
||||
const room = MatrixClientPeg.get().getRoom(roomId);
|
||||
if (!room) {
|
||||
return reject("Bad room ID: " + room_id);
|
||||
return reject("Bad room ID: " + roomId);
|
||||
}
|
||||
var powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
const powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", "",
|
||||
);
|
||||
return success(
|
||||
MatrixClientPeg.get().setPowerLevel(
|
||||
room_id, user_id, powerLevel, powerLevelEvent
|
||||
)
|
||||
roomId, userId, powerLevel, powerLevelEvent,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -262,32 +269,87 @@ var commands = {
|
|||
}),
|
||||
|
||||
// Reset the power level of a user
|
||||
deop: new Command("deop", "<userId>", function(room_id, args) {
|
||||
deop: new Command("deop", "<userId>", function(roomId, args) {
|
||||
if (args) {
|
||||
var matches = args.match(/^(\S+)$/);
|
||||
const matches = args.match(/^(\S+)$/);
|
||||
if (matches) {
|
||||
var room = MatrixClientPeg.get().getRoom(room_id);
|
||||
const room = MatrixClientPeg.get().getRoom(roomId);
|
||||
if (!room) {
|
||||
return reject("Bad room ID: " + room_id);
|
||||
return reject("Bad room ID: " + roomId);
|
||||
}
|
||||
|
||||
var powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", ""
|
||||
const powerLevelEvent = room.currentState.getStateEvents(
|
||||
"m.room.power_levels", "",
|
||||
);
|
||||
return success(
|
||||
MatrixClientPeg.get().setPowerLevel(
|
||||
room_id, args, undefined, powerLevelEvent
|
||||
)
|
||||
roomId, args, undefined, powerLevelEvent,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
return reject(this.getUsage());
|
||||
})
|
||||
}),
|
||||
|
||||
// Verify a user, device, and pubkey tuple
|
||||
verify: new Command("verify", "<userId> <deviceId> <deviceSigningKey>", function(roomId, args) {
|
||||
if (args) {
|
||||
const matches = args.match(/^(\S+) +(\S+) +(\S+)$/);
|
||||
if (matches) {
|
||||
const userId = matches[1];
|
||||
const deviceId = matches[2];
|
||||
const fingerprint = matches[3];
|
||||
|
||||
const device = MatrixClientPeg.get().getStoredDevice(userId, deviceId);
|
||||
if (!device) {
|
||||
return reject(`Unknown (user, device) pair: (${userId}, ${deviceId})`);
|
||||
}
|
||||
|
||||
if (device.isVerified()) {
|
||||
if (device.getFingerprint() === fingerprint) {
|
||||
return reject(`Device already verified!`);
|
||||
} else {
|
||||
return reject(`WARNING: Device already verified, but keys do NOT MATCH!`);
|
||||
}
|
||||
}
|
||||
|
||||
if (device.getFingerprint() === fingerprint) {
|
||||
MatrixClientPeg.get().setDeviceVerified(
|
||||
userId, deviceId, true,
|
||||
);
|
||||
|
||||
// Tell the user we verified everything!
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: "Verified key",
|
||||
description: (
|
||||
<div>
|
||||
<p>
|
||||
The signing key you provided matches the signing key you received
|
||||
from { userId }'s device { deviceId }. Device marked as verified.
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
hasCancelButton: false,
|
||||
});
|
||||
|
||||
return success();
|
||||
} else {
|
||||
return reject(`WARNING: KEY VERIFICATION FAILED! The signing key for ${userId} and device
|
||||
${deviceId} is "${device.getFingerprint()}" which does not match the provided key
|
||||
"${fingerprint}". This could mean your communications are being intercepted!`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return reject(this.getUsage());
|
||||
}),
|
||||
};
|
||||
/* eslint-enable babel/no-invalid-this */
|
||||
|
||||
|
||||
// helpful aliases
|
||||
var aliases = {
|
||||
j: "join"
|
||||
const aliases = {
|
||||
j: "join",
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
|
@ -304,13 +366,13 @@ module.exports = {
|
|||
// IRC-style commands
|
||||
input = input.replace(/\s+$/, "");
|
||||
if (input[0] === "/" && input[1] !== "/") {
|
||||
var bits = input.match(/^(\S+?)( +((.|\n)*))?$/);
|
||||
var cmd, args;
|
||||
const bits = input.match(/^(\S+?)( +((.|\n)*))?$/);
|
||||
let cmd;
|
||||
let args;
|
||||
if (bits) {
|
||||
cmd = bits[1].substring(1).toLowerCase();
|
||||
args = bits[3];
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
cmd = input;
|
||||
}
|
||||
if (cmd === "me") return null;
|
||||
|
@ -319,8 +381,7 @@ module.exports = {
|
|||
}
|
||||
if (commands[cmd]) {
|
||||
return commands[cmd].run(roomId, args);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return reject("Unrecognised command: " + input);
|
||||
}
|
||||
}
|
||||
|
@ -329,12 +390,12 @@ module.exports = {
|
|||
|
||||
getCommandList: function() {
|
||||
// Return all the commands plus /me and /markdown which aren't handled like normal commands
|
||||
var cmds = Object.keys(commands).sort().map(function(cmdKey) {
|
||||
const cmds = Object.keys(commands).sort().map(function(cmdKey) {
|
||||
return commands[cmdKey];
|
||||
});
|
||||
cmds.push(new Command("me", "<action>", function() {}));
|
||||
cmds.push(new Command("markdown", "<on|off>", function() {}));
|
||||
|
||||
return cmds;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
|
|
@ -29,6 +29,7 @@ const Email = require('../../email');
|
|||
const AddThreepid = require('../../AddThreepid');
|
||||
const SdkConfig = require('../../SdkConfig');
|
||||
import AccessibleButton from '../views/elements/AccessibleButton';
|
||||
import * as FormattingUtils from '../../utils/FormattingUtils';
|
||||
|
||||
// if this looks like a release, use the 'version' from package.json; else use
|
||||
// the git sha. Prepend version with v, to look like riot-web version
|
||||
|
@ -46,7 +47,7 @@ const gHVersionLabel = function(repo, token='') {
|
|||
} else {
|
||||
url = `https://github.com/${repo}/commit/${token.split('-')[0]}`;
|
||||
}
|
||||
return <a href={url}>{token}</a>;
|
||||
return <a target="_blank" rel="noopener" href={url}>{token}</a>;
|
||||
};
|
||||
|
||||
// Enumerate some simple 'flip a bit' UI settings (if any).
|
||||
|
@ -603,7 +604,12 @@ module.exports = React.createClass({
|
|||
_renderCryptoInfo: function() {
|
||||
const client = MatrixClientPeg.get();
|
||||
const deviceId = client.deviceId;
|
||||
const identityKey = client.getDeviceEd25519Key() || "<not supported>";
|
||||
let identityKey = client.getDeviceEd25519Key();
|
||||
if (!identityKey) {
|
||||
identityKey = "<not supported>";
|
||||
} else {
|
||||
identityKey = FormattingUtils.formatCryptoKey(identityKey);
|
||||
}
|
||||
|
||||
let importExportButtons = null;
|
||||
|
||||
|
|
76
src/components/views/dialogs/DeviceVerifyDialog.js
Normal file
76
src/components/views/dialogs/DeviceVerifyDialog.js
Normal file
|
@ -0,0 +1,76 @@
|
|||
/*
|
||||
Copyright 2016 OpenMarket Ltd
|
||||
Copyright 2017 Vector Creations Ltd
|
||||
|
||||
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 MatrixClientPeg from '../../../MatrixClientPeg';
|
||||
import sdk from '../../../index';
|
||||
import * as FormattingUtils from '../../../utils/FormattingUtils';
|
||||
|
||||
export default function DeviceVerifyDialog(props) {
|
||||
const QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
|
||||
const key = FormattingUtils.formatCryptoKey(props.device.getFingerprint());
|
||||
const body = (
|
||||
<div>
|
||||
<p>
|
||||
To verify that this device can be trusted, please contact its
|
||||
owner using some other means (e.g. in person or a phone call)
|
||||
and ask them whether the key they see in their User Settings
|
||||
for this device matches the key below:
|
||||
</p>
|
||||
<div className="mx_UserSettings_cryptoSection">
|
||||
<ul>
|
||||
<li><label>Device name:</label> <span>{ props.device.getDisplayName() }</span></li>
|
||||
<li><label>Device ID:</label> <span><code>{ props.device.deviceId}</code></span></li>
|
||||
<li><label>Device key:</label> <span><code><b>{ key }</b></code></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>
|
||||
If it matches, press the verify button below.
|
||||
If it doesnt, then someone else is intercepting this device
|
||||
and you probably want to press the blacklist button instead.
|
||||
</p>
|
||||
<p>
|
||||
In future this verification process will be more sophisticated.
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
|
||||
function onFinished(confirm) {
|
||||
if (confirm) {
|
||||
MatrixClientPeg.get().setDeviceVerified(
|
||||
props.userId, props.device.deviceId, true,
|
||||
);
|
||||
}
|
||||
props.onFinished(confirm);
|
||||
}
|
||||
|
||||
return (
|
||||
<QuestionDialog
|
||||
title="Verify device"
|
||||
description={body}
|
||||
button="I verify that the keys match"
|
||||
onFinished={onFinished}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
DeviceVerifyDialog.propTypes = {
|
||||
userId: React.PropTypes.string.isRequired,
|
||||
device: React.PropTypes.object.isRequired,
|
||||
onFinished: React.PropTypes.func.isRequired,
|
||||
};
|
|
@ -50,42 +50,10 @@ export default React.createClass({
|
|||
},
|
||||
|
||||
onVerifyClick: function() {
|
||||
var QuestionDialog = sdk.getComponent("dialogs.QuestionDialog");
|
||||
Modal.createDialog(QuestionDialog, {
|
||||
title: "Verify device",
|
||||
description: (
|
||||
<div>
|
||||
<p>
|
||||
To verify that this device can be trusted, please contact its
|
||||
owner using some other means (e.g. in person or a phone call)
|
||||
and ask them whether the key they see in their User Settings
|
||||
for this device matches the key below:
|
||||
</p>
|
||||
<div className="mx_UserSettings_cryptoSection">
|
||||
<ul>
|
||||
<li><label>Device name:</label> <span>{ this.state.device.getDisplayName() }</span></li>
|
||||
<li><label>Device ID:</label> <span><code>{ this.state.device.deviceId}</code></span></li>
|
||||
<li><label>Device key:</label> <span><code><b>{ this.state.device.getFingerprint() }</b></code></span></li>
|
||||
</ul>
|
||||
</div>
|
||||
<p>
|
||||
If it matches, press the verify button below.
|
||||
If it doesnt, then someone else is intercepting this device
|
||||
and you probably want to press the blacklist button instead.
|
||||
</p>
|
||||
<p>
|
||||
In future this verification process will be more sophisticated.
|
||||
</p>
|
||||
</div>
|
||||
),
|
||||
button: "I verify that the keys match",
|
||||
onFinished: confirm=>{
|
||||
if (confirm) {
|
||||
MatrixClientPeg.get().setDeviceVerified(
|
||||
this.props.userId, this.state.device.deviceId, true
|
||||
);
|
||||
}
|
||||
},
|
||||
const DeviceVerifyDialog = sdk.getComponent('views.dialogs.DeviceVerifyDialog');
|
||||
Modal.createDialog(DeviceVerifyDialog, {
|
||||
userId: this.props.userId,
|
||||
device: this.state.device,
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ export default class DirectorySearchBox extends React.Component {
|
|||
className="mx_DirectorySearchBox_input"
|
||||
ref={this._collectInput}
|
||||
onChange={this._onChange} onKeyUp={this._onKeyUp}
|
||||
placeholder={this.props.placeholder}
|
||||
placeholder={this.props.placeholder} autoFocus
|
||||
/>
|
||||
{join_button}
|
||||
<span className="mx_DirectorySearchBox_clear_wrapper">
|
||||
|
|
|
@ -26,3 +26,14 @@ export function formatCount(count) {
|
|||
if (count < 100000000) return (count / 1000000).toFixed(0) + "M";
|
||||
return (count / 1000000000).toFixed(1) + "B"; // 10B is enough for anyone, right? :S
|
||||
}
|
||||
|
||||
/**
|
||||
* format a key into groups of 4 characters, for easier visual inspection
|
||||
*
|
||||
* @param {string} key key to format
|
||||
*
|
||||
* @return {string}
|
||||
*/
|
||||
export function formatCryptoKey(key) {
|
||||
return key.match(/.{1,4}/g).join(" ");
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue