From 6ab89a801b4c3b66ff3e0feecb7085b1e78ae414 Mon Sep 17 00:00:00 2001 From: Vincent Date: Tue, 21 Jan 2020 12:58:49 +1100 Subject: [PATCH] Settings lock completion --- js/background.js | 6 +- stylesheets/_session.scss | 16 ++-- .../session/settings/SessionSettings.tsx | 93 ++++++++++++++----- 3 files changed, 80 insertions(+), 35 deletions(-) diff --git a/js/background.js b/js/background.js index 8e8d6a669..09f38dd4b 100644 --- a/js/background.js +++ b/js/background.js @@ -907,17 +907,17 @@ }; window.toggleMenuBar = () => { - const newValue = ! window.getSettingValue('hide-menu-bar'); + const newValue = !window.getSettingValue('hide-menu-bar'); window.Events.setHideMenuBar(newValue); }; window.toggleSpellCheck = () => { - const newValue = ! window.getSettingValue('spell-check'); + const newValue = !window.getSettingValue('spell-check'); window.Events.setSpellCheck(newValue); }; window.toggleLinkPreview = () => { - const newValue = ! window.getSettingValue('link-preview-setting'); + const newValue = !window.getSettingValue('link-preview-setting'); window.Events.setLinkPreviewSetting(newValue); }; diff --git a/stylesheets/_session.scss b/stylesheets/_session.scss index 46b0b0d9a..838543790 100644 --- a/stylesheets/_session.scss +++ b/stylesheets/_session.scss @@ -345,7 +345,7 @@ $session_message-container-border-radius: 5px; border-radius: 0px; } - & > *:not(svg):hover { + & > *:hover:not(svg) { filter: brightness(80%); } } @@ -978,13 +978,13 @@ label { } } - &__password-lock{ + &__password-lock { display: flex; align-items: center; justify-content: center; flex-grow: 1; - - &-box{ + + &-box { padding: 45px 60px; display: flex; flex-direction: column; @@ -1011,13 +1011,12 @@ label { outline: none; border: none; border-radius: 2px; - text-align:center; + text-align: center; font-size: 25px; letter-spacing: 5px; - font-family: "SF Pro Text"; + font-family: 'SF Pro Text'; } - - } + } } } @@ -1225,4 +1224,3 @@ button.module-scroll-down { background-color: $session-shade-8; } } - diff --git a/ts/components/session/settings/SessionSettings.tsx b/ts/components/session/settings/SessionSettings.tsx index d18809c2c..0f6e15dc0 100644 --- a/ts/components/session/settings/SessionSettings.tsx +++ b/ts/components/session/settings/SessionSettings.tsx @@ -2,7 +2,11 @@ import React from 'react'; import { SettingsHeader } from './SessionSettingsHeader'; import { SessionSettingListItem } from './SessionSettingListItem'; -import { SessionButtonColor, SessionButton, SessionButtonType } from '../SessionButton'; +import { + SessionButton, + SessionButtonColor, + SessionButtonType, +} from '../SessionButton'; export enum SessionSettingCategory { General = 'general', @@ -26,6 +30,8 @@ export interface SettingsViewProps { interface State { hasPassword: boolean | null; + shouldLockSettings: boolean | null; + pwdLockError: string | null; } export class SettingsView extends React.Component { @@ -36,10 +42,13 @@ export class SettingsView extends React.Component { this.state = { hasPassword: null, + pwdLockError: null, + shouldLockSettings: true, }; this.settingsViewRef = React.createRef(); this.onPasswordUpdated = this.onPasswordUpdated.bind(this); + this.validatePasswordLock = this.validatePasswordLock.bind(this); this.hasPassword(); } @@ -104,7 +113,8 @@ export class SettingsView extends React.Component { content: { options: { group: 'notification-setting', - initalItem: window.getSettingValue('notification-setting') || 'message', + initalItem: + window.getSettingValue('notification-setting') || 'message', items: [ { label: window.i18n('nameAndMessage'), @@ -214,7 +224,7 @@ export class SettingsView extends React.Component { const description = setting.description || ''; const comparisonValue = setting.comparisonValue || null; - const value = + const value = window.getSettingValue(setting.id, comparisonValue) || setting.content.defaultValue; @@ -251,31 +261,67 @@ export class SettingsView extends React.Component { ); } - public renderPasswordLock() { - return (
-

- {window.i18n('password')} -

+

{window.i18n('password')}

+ + {this.state.pwdLockError && ( + <> +
+ {this.state.pwdLockError} +
+
+ + )} + -
); } + public async validatePasswordLock() { + const enteredPassword = String($('#password-lock-input').val()); + + if (!enteredPassword) { + this.setState({ + pwdLockError: window.i18n('noGivenPassword'), + }); + + return false; + } + + // Check if the password matches the hash we have stored + const hash = await window.Signal.Data.getPasswordHash(); + if (hash && !window.passwordUtil.matchesHash(enteredPassword, hash)) { + this.setState({ + pwdLockError: window.i18n('invalidPassword'), + }); + + return false; + } + + // Unlocked settings + this.setState({ + shouldLockSettings: false, + }); + + return true; + } + public hasPassword() { const hashPromise = window.Signal.Data.getPasswordHash(); @@ -288,19 +334,19 @@ export class SettingsView extends React.Component { public render() { const { category } = this.props; - const shouldRenderPasswordLock = this.state.hasPassword === true; + const shouldRenderPasswordLock = + this.state.shouldLockSettings && this.state.hasPassword; return (
- {shouldRenderPasswordLock - ? this.renderPasswordLock() - : ( -
- { this.renderSettingInCategory() } -
- ) - } + {shouldRenderPasswordLock ? ( + this.renderPasswordLock() + ) : ( +
+ {this.renderSettingInCategory()} +
+ )}
); } @@ -314,7 +360,7 @@ export class SettingsView extends React.Component { if (item.type === SessionSettingType.Toggle) { // If no custom afterClick function given, alter values in storage here // Switch to opposite state - const newValue = ! window.getSettingValue(item.id); + const newValue = !window.getSettingValue(item.id); window.setSettingValue(item.id, newValue); } } @@ -326,9 +372,10 @@ export class SettingsView extends React.Component { } public onPasswordUpdated(action: string) { - if (action === 'set') { + if (action === 'set' || action === 'change') { this.setState({ hasPassword: true, + shouldLockSettings: true, }); }