From 5771406dd7d0c691082515461b0fa5d8d28594d2 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Mon, 18 Mar 2019 23:21:21 +0000 Subject: [PATCH 01/28] Add View Servers in Room to Devtools Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/dialogs/_DevtoolsDialog.scss | 6 ++- .../views/dialogs/DevtoolsDialog.js | 44 +++++++++++++++++++ src/i18n/strings/en_EN.json | 1 + 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss index 815e8408b5..f38191445c 100644 --- a/res/css/views/dialogs/_DevtoolsDialog.scss +++ b/res/css/views/dialogs/_DevtoolsDialog.scss @@ -18,7 +18,11 @@ limitations under the License. margin: 10px 0; } -.mx_DevTools_RoomStateExplorer_button, .mx_DevTools_RoomStateExplorer_query { +.mx_DevTools_ServersInRoomList_button { + cursor: default !important; +} + +.mx_DevTools_RoomStateExplorer_button, .mx_DevTools_ServersInRoomList_button, .mx_DevTools_RoomStateExplorer_query { margin-bottom: 10px; width: 100%; } diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index 3db516a74d..f7ddb542ae 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -551,11 +551,55 @@ class AccountDataExplorer extends DevtoolsComponent { } } +class ServersInRoomList extends DevtoolsComponent { + static getLabel() { return _t('View Servers in Room'); } + + static propTypes = { + onBack: PropTypes.func.isRequired, + }; + + constructor(props, context) { + super(props, context); + + this.onQuery = this.onQuery.bind(this); + + const room = MatrixClientPeg.get().getRoom(this.context.roomId); + const servers = new Set(); + room.currentState.getStateEvents("m.room.member").forEach(ev => servers.add(ev.getSender().split(":")[1])); + this.servers = Array.from(servers).map(s => + ); + + this.state = { + query: '', + }; + } + + onQuery(query) { + this.setState({ query }); + } + + render() { + return
+
+ + { this.servers } + +
+
+ +
+
; + } +} + const Entries = [ SendCustomEvent, RoomStateExplorer, SendAccountData, AccountDataExplorer, + ServersInRoomList, ]; export default class DevtoolsDialog extends React.Component { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index e23be021e8..60fd373306 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1095,6 +1095,7 @@ "Filter results": "Filter results", "Explore Room State": "Explore Room State", "Explore Account Data": "Explore Account Data", + "View Servers in Room": "View Servers in Room", "Toolbox": "Toolbox", "Developer Tools": "Developer Tools", "An error has occurred.": "An error has occurred.", From c636f890b5a6c97c872cec3583620e93395d4c31 Mon Sep 17 00:00:00 2001 From: Travis Ralston Date: Mon, 6 May 2019 09:55:27 -0600 Subject: [PATCH 02/28] Add configuration flag to disable minimum password requirements The configuration flag is intentionally long and annoying - the vast majority of people should not need this. The flag is intended to be used in development environments where accounts are often registered with no intention of them sticking around. --- src/components/views/auth/RegistrationForm.js | 16 ++++++++++++++-- src/i18n/strings/en_EN.json | 1 + 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/views/auth/RegistrationForm.js b/src/components/views/auth/RegistrationForm.js index 6e55581af0..eb77e125af 100644 --- a/src/components/views/auth/RegistrationForm.js +++ b/src/components/views/auth/RegistrationForm.js @@ -76,6 +76,7 @@ module.exports = React.createClass({ password: "", passwordConfirm: "", passwordComplexity: null, + passwordUnsafe: false, }; }, @@ -270,12 +271,23 @@ module.exports = React.createClass({ } const { scorePassword } = await import('../../../utils/PasswordScorer'); const complexity = scorePassword(value); + const unsafe = complexity.score < PASSWORD_MIN_SCORE; + const allowUnsafe = SdkConfig.get()["dangerously_allow_unsafe_and_insecure_passwords"]; this.setState({ passwordComplexity: complexity, + passwordUnsafe: unsafe, }); - return complexity.score >= PASSWORD_MIN_SCORE; + return allowUnsafe || !unsafe; + }, + valid: function() { + // Unsafe passwords that are valid are only possible through a + // configuration flag. We'll print some helper text to signal + // to the user that their password is allowed, but unsafe. + if (this.state.passwordUnsafe) { + return _t("Password is allowed, but unsafe"); + } + return _t("Nice, strong password!"); }, - valid: () => _t("Nice, strong password!"), invalid: function() { const complexity = this.state.passwordComplexity; if (!complexity) { diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index eaea057b36..273ca8a571 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -1327,6 +1327,7 @@ "Enter email address (required on this homeserver)": "Enter email address (required on this homeserver)", "Doesn't look like a valid email address": "Doesn't look like a valid email address", "Enter password": "Enter password", + "Password is allowed, but unsafe": "Password is allowed, but unsafe", "Nice, strong password!": "Nice, strong password!", "Keep going...": "Keep going...", "Passwords don't match": "Passwords don't match", From 92a932158df32e8360c649df1c5280390652595b Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 9 May 2019 22:12:21 +0100 Subject: [PATCH 03/28] Command to change avatar for a single room, including upload of mxc res Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- src/SlashCommands.js | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/SlashCommands.js b/src/SlashCommands.js index f72ba1e005..8757f5108a 100644 --- a/src/SlashCommands.js +++ b/src/SlashCommands.js @@ -1,6 +1,7 @@ /* Copyright 2015, 2016 OpenMarket Ltd Copyright 2018 New Vector Ltd +Copyright 2019 Michael Telatynski <7t3chguy@gmail.com> Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -30,6 +31,7 @@ import MultiInviter from './utils/MultiInviter'; import { linkifyAndSanitizeHtml } from './HtmlUtils'; import QuestionDialog from "./components/views/dialogs/QuestionDialog"; import WidgetUtils from "./utils/WidgetUtils"; +import Promise from "bluebird"; class Command { constructor({name, args='', description, runFn, hideCompletionAfterSpace=false}) { @@ -208,6 +210,47 @@ export const CommandMap = { }, }), + roomavatar: new Command({ + name: 'roomavatar', + args: '', + description: _td('Changes your avatar in this current room only'), + runFn: function(roomId, args) { + const cli = MatrixClientPeg.get(); + const room = cli.getRoom(roomId); + const userId = cli.getUserId(); + + let promise = Promise.resolve(args); + if (!args) { + promise = new Promise((resolve) => { + const fileSelector = document.createElement('input'); + fileSelector.setAttribute('type', 'file'); + fileSelector.onchange = (ev) => { + const file = ev.target.files[0]; + + const UploadConfirmDialog = sdk.getComponent("dialogs.UploadConfirmDialog"); + Modal.createTrackedDialog('Upload Files confirmation', '', UploadConfirmDialog, { + file, + onFinished: (shouldContinue) => { + if (shouldContinue) resolve(cli.uploadContent(file)); + }, + }); + }; + + fileSelector.click(); + }); + } + + return success(promise.then((url) => { + const ev = room.currentState.getStateEvents('m.room.member', userId); + const content = { + ...ev ? ev.getContent() : { membership: 'join' }, + avatar_url: url, + }; + return cli.sendStateEvent(roomId, 'm.room.member', content, userId); + })); + }, + }), + tint: new Command({ name: 'tint', args: ' []', From cd5a460b2b257029ee0e1ff8d1544ea3a88fa317 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Thu, 9 May 2019 22:30:45 +0100 Subject: [PATCH 04/28] Iterate PR based on feedback Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- res/css/views/dialogs/_DevtoolsDialog.scss | 1 + src/components/views/dialogs/DevtoolsDialog.js | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/res/css/views/dialogs/_DevtoolsDialog.scss b/res/css/views/dialogs/_DevtoolsDialog.scss index f38191445c..2f01f3ecc6 100644 --- a/res/css/views/dialogs/_DevtoolsDialog.scss +++ b/res/css/views/dialogs/_DevtoolsDialog.scss @@ -19,6 +19,7 @@ limitations under the License. } .mx_DevTools_ServersInRoomList_button { + /* Set the cursor back to default as `.mx_Dialog button` sets it to pointer */ cursor: default !important; } diff --git a/src/components/views/dialogs/DevtoolsDialog.js b/src/components/views/dialogs/DevtoolsDialog.js index f7ddb542ae..0835c41bb9 100644 --- a/src/components/views/dialogs/DevtoolsDialog.js +++ b/src/components/views/dialogs/DevtoolsDialog.js @@ -561,8 +561,6 @@ class ServersInRoomList extends DevtoolsComponent { constructor(props, context) { super(props, context); - this.onQuery = this.onQuery.bind(this); - const room = MatrixClientPeg.get().getRoom(this.context.roomId); const servers = new Set(); room.currentState.getStateEvents("m.room.member").forEach(ev => servers.add(ev.getSender().split(":")[1])); @@ -576,7 +574,7 @@ class ServersInRoomList extends DevtoolsComponent { }; } - onQuery(query) { + onQuery = (query) => { this.setState({ query }); } From 3beb70814c8b699f3d3d81da8dd36015bd635d14 Mon Sep 17 00:00:00 2001 From: "J. Ryan Stinnett" Date: Tue, 7 May 2019 15:40:02 +0100 Subject: [PATCH 05/28] Fix indentation in TimelinePanel --- src/components/structures/TimelinePanel.js | 50 +++++++++++----------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/src/components/structures/TimelinePanel.js b/src/components/structures/TimelinePanel.js index aa278f2349..e065c5719e 100644 --- a/src/components/structures/TimelinePanel.js +++ b/src/components/structures/TimelinePanel.js @@ -1193,9 +1193,9 @@ const TimelinePanel = React.createClass({ if (this.state.events.length == 0 && !this.state.canBackPaginate && this.props.empty) { return ( -
-
{ this.props.empty }
-
+
+
{this.props.empty}
+
); } @@ -1217,28 +1217,28 @@ const TimelinePanel = React.createClass({ ); return (