UI for blacklisting unverified devices per-room & globally
(written blind; untested as yet)
This commit is contained in:
parent
2e15e8f9b4
commit
3071fc0ddc
4 changed files with 94 additions and 3 deletions
|
@ -149,6 +149,22 @@ module.exports = {
|
||||||
return MatrixClientPeg.get().setAccountData("im.vector.web.settings", settings);
|
return MatrixClientPeg.get().setAccountData("im.vector.web.settings", settings);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getLocalSettings: function() {
|
||||||
|
return localStorage.getItem('mx_local_settings');
|
||||||
|
},
|
||||||
|
|
||||||
|
getLocalSetting: function(type, defaultValue = null) {
|
||||||
|
var settings = this.getLocalSettings();
|
||||||
|
return settings.hasOwnProperty(type) ? settings[type] : null;
|
||||||
|
},
|
||||||
|
|
||||||
|
setLocalSetting: function(type, value) {
|
||||||
|
var settings = this.getLocalSettings();
|
||||||
|
settings[type] = value;
|
||||||
|
// FIXME: handle errors
|
||||||
|
localStorage.setItem('mx_local_settings', settings);
|
||||||
|
},
|
||||||
|
|
||||||
isFeatureEnabled: function(feature: string): boolean {
|
isFeatureEnabled: function(feature: string): boolean {
|
||||||
// Disable labs for guests.
|
// Disable labs for guests.
|
||||||
if (MatrixClientPeg.get().isGuest()) return false;
|
if (MatrixClientPeg.get().isGuest()) return false;
|
||||||
|
|
|
@ -57,6 +57,18 @@ const SETTINGS_LABELS = [
|
||||||
*/
|
*/
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const CRYPTO_SETTINGS_LABELS = [
|
||||||
|
{
|
||||||
|
id: 'blacklistUnverifiedDevices',
|
||||||
|
label: 'Never send encrypted messages to unverified devices',
|
||||||
|
},
|
||||||
|
// XXX: this is here for documentation; the actual setting is managed via RoomSettings
|
||||||
|
// {
|
||||||
|
// id: 'blacklistUnverifiedDevicesPerRoom'
|
||||||
|
// label: 'Never send encrypted messages to unverified devices in this room',
|
||||||
|
// }
|
||||||
|
];
|
||||||
|
|
||||||
// Enumerate the available themes, with a nice human text label.
|
// Enumerate the available themes, with a nice human text label.
|
||||||
// 'id' gives the key name in the im.vector.web.settings account data event
|
// 'id' gives the key name in the im.vector.web.settings account data event
|
||||||
// 'value' is the value for that key in the event
|
// 'value' is the value for that key in the event
|
||||||
|
@ -146,6 +158,8 @@ module.exports = React.createClass({
|
||||||
syncedSettings.theme = 'light';
|
syncedSettings.theme = 'light';
|
||||||
}
|
}
|
||||||
this._syncedSettings = syncedSettings;
|
this._syncedSettings = syncedSettings;
|
||||||
|
|
||||||
|
this._localSettings = UserSettingsStore.getLocalSettings();
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
@ -471,10 +485,32 @@ module.exports = React.createClass({
|
||||||
<li><label>Device key:</label> <span><code><b>{identityKey}</b></code></span></li>
|
<li><label>Device key:</label> <span><code><b>{identityKey}</b></code></span></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
{ CRYPTO_SETTINGS_LABELS.map( this._renderLocalSetting ) }
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_renderLocalSetting: function(setting) {
|
||||||
|
const client = MatrixClientPeg.get();
|
||||||
|
return <div className="mx_UserSettings_toggle" key={ setting.id }>
|
||||||
|
<input id={ setting.id }
|
||||||
|
type="checkbox"
|
||||||
|
defaultChecked={ this._localSettings[setting.id] }
|
||||||
|
onChange={
|
||||||
|
e => {
|
||||||
|
UserSettingsStore.setLocalSetting(setting.id, e.target.checked)
|
||||||
|
if (setting.id === 'blacklistUnverifiedDevices') { // XXX: this is a bit ugly
|
||||||
|
client.setGlobalBlacklistUnverifiedDevices(e.target.checked);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<label htmlFor={ setting.id }>
|
||||||
|
{ setting.label }
|
||||||
|
</label>
|
||||||
|
</div>;
|
||||||
|
},
|
||||||
|
|
||||||
_renderDevicesPanel: function() {
|
_renderDevicesPanel: function() {
|
||||||
var DevicesPanel = sdk.getComponent('settings.DevicesPanel');
|
var DevicesPanel = sdk.getComponent('settings.DevicesPanel');
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -69,5 +69,7 @@ module.exports = React.createClass({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
// XXX: do we want to give the user the option to enable blacklistUnverifiedDevices for this room (or globally) at this point?
|
||||||
|
// It feels like confused users will likely turn it on and then disappear in a cloud of UISIs...
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -228,11 +228,13 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
|
|
||||||
// encryption
|
// encryption
|
||||||
p = this.saveEncryption();
|
p = this.saveEnableEncryption();
|
||||||
if (!q.isFulfilled(p)) {
|
if (!q.isFulfilled(p)) {
|
||||||
promises.push(p);
|
promises.push(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.saveBlacklistUnverifiedDevicesPerRoom();
|
||||||
|
|
||||||
console.log("Performing %s operations: %s", promises.length, JSON.stringify(promises));
|
console.log("Performing %s operations: %s", promises.length, JSON.stringify(promises));
|
||||||
return promises;
|
return promises;
|
||||||
},
|
},
|
||||||
|
@ -252,11 +254,11 @@ module.exports = React.createClass({
|
||||||
return this.refs.url_preview_settings.saveSettings();
|
return this.refs.url_preview_settings.saveSettings();
|
||||||
},
|
},
|
||||||
|
|
||||||
saveEncryption: function() {
|
saveEnableEncryption: function() {
|
||||||
if (!this.refs.encrypt) { return q(); }
|
if (!this.refs.encrypt) { return q(); }
|
||||||
|
|
||||||
var encrypt = this.refs.encrypt.checked;
|
var encrypt = this.refs.encrypt.checked;
|
||||||
if (!encrypt) { return q(); }
|
if (encrypt) { return q(); }
|
||||||
|
|
||||||
var roomId = this.props.room.roomId;
|
var roomId = this.props.room.roomId;
|
||||||
return MatrixClientPeg.get().sendStateEvent(
|
return MatrixClientPeg.get().sendStateEvent(
|
||||||
|
@ -265,6 +267,29 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
saveBlacklistUnverifiedDevicesPerRoom: function() {
|
||||||
|
if (!this.refs.blacklistUnverified) return;
|
||||||
|
if (this._isRoomBlacklistUnverified() !== this.refs.blacklistUnverified.checked) {
|
||||||
|
this._setRoomBlacklistUnverified(this.refs.blacklistUnverified.checked);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
_isRoomBlacklistUnverified: function() {
|
||||||
|
var blacklistUnverifiedDevicesPerRoom = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevicesPerRoom;
|
||||||
|
if (blacklistUnverifiedDevicesPerRoom) {
|
||||||
|
return blacklistUnverifiedDevicesPerRoom[this.props.room.roomId];
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
_setRoomBlacklistUnverified: function(value) {
|
||||||
|
var blacklistUnverifiedDevicesPerRoom = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevicesPerRoom;
|
||||||
|
blacklistUnverifiedDevicesPerRoom[this.props.room.roomId] = value;
|
||||||
|
UserSettingsStore.setLocalSettings('blacklistUnverifiedDevicesPerRoom', blacklistUnverifiedDevicesPerRoom);
|
||||||
|
|
||||||
|
this.props.room.setBlacklistUnverifiedDevices(value);
|
||||||
|
},
|
||||||
|
|
||||||
_hasDiff: function(strA, strB) {
|
_hasDiff: function(strA, strB) {
|
||||||
// treat undefined as an empty string because other components may blindly
|
// treat undefined as an empty string because other components may blindly
|
||||||
// call setName("") when there has been no diff made to the name!
|
// call setName("") when there has been no diff made to the name!
|
||||||
|
@ -477,6 +502,16 @@ module.exports = React.createClass({
|
||||||
var cli = MatrixClientPeg.get();
|
var cli = MatrixClientPeg.get();
|
||||||
var roomState = this.props.room.currentState;
|
var roomState = this.props.room.currentState;
|
||||||
var isEncrypted = cli.isRoomEncrypted(this.props.room.roomId);
|
var isEncrypted = cli.isRoomEncrypted(this.props.room.roomId);
|
||||||
|
var isGlobalBlacklistUnverified = UserSettingsStore.getLocalSettings().blacklistUnverifiedDevices;
|
||||||
|
var isRoomBlacklistUnverified = this._isRoomBlacklistUnverified();
|
||||||
|
|
||||||
|
var settings =
|
||||||
|
<label>
|
||||||
|
<input type="checkbox" ref="blacklistUnverified"
|
||||||
|
checked={ isGlobalBlacklistUnverified || isRoomBlacklistUnverified }
|
||||||
|
disabled={ isGlobalBlacklistUnverified || !this.refs.encrypt.checked }/>
|
||||||
|
Never send encrypted messages to unverified devices in this room.
|
||||||
|
</label>;
|
||||||
|
|
||||||
if (!isEncrypted &&
|
if (!isEncrypted &&
|
||||||
roomState.mayClientSendStateEvent("m.room.encryption", cli)) {
|
roomState.mayClientSendStateEvent("m.room.encryption", cli)) {
|
||||||
|
@ -486,6 +521,7 @@ module.exports = React.createClass({
|
||||||
<img className="mx_RoomSettings_e2eIcon" src="img/e2e-unencrypted.svg" width="12" height="12" />
|
<img className="mx_RoomSettings_e2eIcon" src="img/e2e-unencrypted.svg" width="12" height="12" />
|
||||||
Enable encryption (warning: cannot be disabled again!)
|
Enable encryption (warning: cannot be disabled again!)
|
||||||
</label>
|
</label>
|
||||||
|
{ settings }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -497,6 +533,7 @@ module.exports = React.createClass({
|
||||||
}
|
}
|
||||||
Encryption is { isEncrypted ? "" : "not " } enabled in this room.
|
Encryption is { isEncrypted ? "" : "not " } enabled in this room.
|
||||||
</label>
|
</label>
|
||||||
|
{ settings }
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue