Merge pull request #3059 from Bilb/fix-dont-password-protect-settings

feat: dont password protect the settings except the seed one
pull/3067/head
Audric Ackermann 2 months ago committed by GitHub
commit 5f6af1e2cb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -25,13 +25,9 @@ const StyledButtonContainer = styled.div`
padding-inline-start: var(--margins-lg);
`;
export const SessionNotificationGroupSettings = (props: { hasPassword: boolean | null }) => {
export const SessionNotificationGroupSettings = () => {
const forceUpdate = useUpdate();
if (props.hasPassword === null) {
return null;
}
const initialNotificationEnabled =
window.getSettingValue(SettingsKey.settingsNotification) || NOTIFICATION.MESSAGE;

@ -1,23 +1,24 @@
import { shell } from 'electron';
import React from 'react';
import autoBind from 'auto-bind';
import React, { useState } from 'react';
import styled from 'styled-components';
import { useDispatch } from 'react-redux';
import useMount from 'react-use/lib/useMount';
import { SettingsHeader } from './SessionSettingsHeader';
import { SessionIconButton } from '../icon';
import { SessionNotificationGroupSettings } from './SessionNotificationGroupSettings';
import { CategoryConversations } from './section/CategoryConversations';
import { SettingsCategoryPrivacy } from './section/CategoryPrivacy';
import { SettingsCategoryAppearance } from './section/CategoryAppearance';
import { Data } from '../../data/data';
import { SettingsCategoryPermissions } from './section/CategoryPermissions';
import { SettingsCategoryHelp } from './section/CategoryHelp';
import { sessionPassword } from '../../state/ducks/modalDialog';
import { PasswordAction } from '../dialog/SessionPasswordDialog';
import { SectionType, showLeftPaneSection } from '../../state/ducks/section';
import { PasswordAction } from '../dialog/SessionPasswordDialog';
import { SettingsCategoryAppearance } from './section/CategoryAppearance';
import { CategoryConversations } from './section/CategoryConversations';
import { SettingsCategoryHelp } from './section/CategoryHelp';
import { SettingsCategoryPermissions } from './section/CategoryPermissions';
import { SettingsCategoryPrivacy } from './section/CategoryPrivacy';
export function displayPasswordModal(
passwordAction: PasswordAction,
@ -57,11 +58,6 @@ export interface SettingsViewProps {
category: SessionSettingCategory;
}
interface State {
hasPassword: boolean | null;
shouldLockSettings: boolean | null;
}
const StyledVersionInfo = styled.div`
display: flex;
justify-content: space-between;
@ -110,30 +106,27 @@ const SessionInfo = () => {
const SettingInCategory = (props: {
category: SessionSettingCategory;
hasPassword: boolean;
onPasswordUpdated: (action: string) => void;
hasPassword: boolean;
}) => {
const { category, hasPassword, onPasswordUpdated } = props;
const { category, onPasswordUpdated, hasPassword } = props;
if (hasPassword === null) {
return null;
}
switch (category) {
// special case for blocked user
case SessionSettingCategory.Conversations:
return <CategoryConversations />;
case SessionSettingCategory.Appearance:
return <SettingsCategoryAppearance hasPassword={hasPassword} />;
return <SettingsCategoryAppearance />;
case SessionSettingCategory.Notifications:
return <SessionNotificationGroupSettings hasPassword={hasPassword} />;
return <SessionNotificationGroupSettings />;
case SessionSettingCategory.Privacy:
return (
<SettingsCategoryPrivacy onPasswordUpdated={onPasswordUpdated} hasPassword={hasPassword} />
);
case SessionSettingCategory.Help:
return <SettingsCategoryHelp hasPassword={hasPassword} />;
return <SettingsCategoryHelp />;
case SessionSettingCategory.Permissions:
return <SettingsCategoryPermissions hasPassword={hasPassword} />;
return <SettingsCategoryPermissions />;
// these three down there have no options, they are just a button
case SessionSettingCategory.ClearData:
@ -159,87 +152,48 @@ const StyledSettingsList = styled.div`
flex-direction: column;
`;
export class SessionSettingsView extends React.Component<SettingsViewProps, State> {
public settingsViewRef: React.RefObject<HTMLDivElement>;
public constructor(props: any) {
super(props);
this.state = {
hasPassword: null,
shouldLockSettings: true,
};
this.settingsViewRef = React.createRef();
autoBind(this);
export const SessionSettingsView = (props: SettingsViewProps) => {
const { category } = props;
const dispatch = useDispatch();
const [hasPassword, setHasPassword] = useState(true);
useMount(() => {
let isMounted = true;
// eslint-disable-next-line more/no-then
void Data.getPasswordHash().then(hash => {
this.setState({
hasPassword: !!hash,
});
if (isMounted) {
setHasPassword(!!hash);
}
});
}
public componentDidUpdate(_: SettingsViewProps, _prevState: State) {
const oldShouldRenderPasswordLock = _prevState.shouldLockSettings && _prevState.hasPassword;
const newShouldRenderPasswordLock = this.state.shouldLockSettings && this.state.hasPassword;
if (
newShouldRenderPasswordLock &&
newShouldRenderPasswordLock !== oldShouldRenderPasswordLock
) {
displayPasswordModal('enter', action => {
if (action === 'enter') {
// Unlocked settings
this.setState({
shouldLockSettings: false,
});
}
});
}
}
public render() {
const { category } = this.props;
const shouldRenderPasswordLock = this.state.shouldLockSettings && this.state.hasPassword;
return (
<div className="session-settings">
{shouldRenderPasswordLock ? (
<></>
) : (
<>
<SettingsHeader category={category} />
<StyledSettingsView>
<StyledSettingsList ref={this.settingsViewRef}>
<SettingInCategory
category={category}
onPasswordUpdated={this.onPasswordUpdated}
hasPassword={Boolean(this.state.hasPassword)}
/>
</StyledSettingsList>
<SessionInfo />
</StyledSettingsView>
</>
)}
</div>
);
}
return () => {
isMounted = false;
};
});
public onPasswordUpdated(action: string) {
function onPasswordUpdated(action: string) {
if (action === 'set' || action === 'change') {
this.setState({
hasPassword: true,
shouldLockSettings: true,
});
window.inboxStore?.dispatch(showLeftPaneSection(SectionType.Message));
setHasPassword(true);
dispatch(showLeftPaneSection(SectionType.Message));
}
if (action === 'remove') {
this.setState({
hasPassword: false,
});
setHasPassword(false);
}
}
}
return (
<div className="session-settings">
<SettingsHeader category={category} />
<StyledSettingsView>
<StyledSettingsList>
<SettingInCategory
category={category}
onPasswordUpdated={onPasswordUpdated}
hasPassword={hasPassword}
/>
</StyledSettingsList>
<SessionInfo />
</StyledSettingsView>
</div>
);
};

@ -2,54 +2,51 @@ import React from 'react';
import useUpdate from 'react-use/lib/useUpdate';
import { SettingsKey } from '../../../data/settings-key';
import { isHideMenuBarSupported } from '../../../types/Settings';
import { useHasFollowSystemThemeEnabled } from '../../../state/selectors/settings';
import { ensureThemeConsistency } from '../../../themes/SessionTheme';
import { isHideMenuBarSupported } from '../../../types/Settings';
import { SessionToggleWithDescription } from '../SessionSettingListItem';
import { SettingsThemeSwitcher } from '../SettingsThemeSwitcher';
import { ZoomingSessionSlider } from '../ZoomingSessionSlider';
export const SettingsCategoryAppearance = (props: { hasPassword: boolean | null }) => {
export const SettingsCategoryAppearance = () => {
const forceUpdate = useUpdate();
const isFollowSystemThemeEnabled = useHasFollowSystemThemeEnabled();
if (props.hasPassword !== null) {
const isHideMenuBarActive =
window.getSettingValue(SettingsKey.settingsMenuBar) === undefined
? true
: window.getSettingValue(SettingsKey.settingsMenuBar);
const isHideMenuBarActive =
window.getSettingValue(SettingsKey.settingsMenuBar) === undefined
? true
: window.getSettingValue(SettingsKey.settingsMenuBar);
return (
<>
<SettingsThemeSwitcher />
<ZoomingSessionSlider />
{isHideMenuBarSupported() && (
<SessionToggleWithDescription
onClickToggle={() => {
window.toggleMenuBar();
forceUpdate();
}}
title={window.i18n('hideMenuBarTitle')}
description={window.i18n('hideMenuBarDescription')}
active={isHideMenuBarActive}
/>
)}
return (
<>
<SettingsThemeSwitcher />
<ZoomingSessionSlider />
{isHideMenuBarSupported() && (
<SessionToggleWithDescription
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onClickToggle={async () => {
const toggledValue = !isFollowSystemThemeEnabled;
await window.setSettingValue(SettingsKey.hasFollowSystemThemeEnabled, toggledValue);
if (!isFollowSystemThemeEnabled) {
await ensureThemeConsistency();
}
onClickToggle={() => {
window.toggleMenuBar();
forceUpdate();
}}
title={window.i18n('matchThemeSystemSettingTitle')}
description={window.i18n('matchThemeSystemSettingDescription')}
active={isFollowSystemThemeEnabled}
dataTestId="enable-follow-system-theme"
title={window.i18n('hideMenuBarTitle')}
description={window.i18n('hideMenuBarDescription')}
active={isHideMenuBarActive}
/>
</>
);
}
return null;
)}
<SessionToggleWithDescription
// eslint-disable-next-line @typescript-eslint/no-misused-promises
onClickToggle={async () => {
const toggledValue = !isFollowSystemThemeEnabled;
await window.setSettingValue(SettingsKey.hasFollowSystemThemeEnabled, toggledValue);
if (!isFollowSystemThemeEnabled) {
await ensureThemeConsistency();
}
}}
title={window.i18n('matchThemeSystemSettingTitle')}
description={window.i18n('matchThemeSystemSettingDescription')}
active={isFollowSystemThemeEnabled}
dataTestId="enable-follow-system-theme"
/>
</>
);
};

@ -4,38 +4,35 @@ import { SessionButtonShape, SessionButtonType } from '../../basic/SessionButton
import { SessionSettingButtonItem, SessionSettingsTitleWithLink } from '../SessionSettingListItem';
export const SettingsCategoryHelp = (props: { hasPassword: boolean | null }) => {
if (props.hasPassword !== null) {
return (
<>
<SessionSettingButtonItem
onClick={() => {
ipcRenderer.send('show-debug-log');
}}
buttonShape={SessionButtonShape.Square}
buttonType={SessionButtonType.Solid}
buttonText={window.i18n('showDebugLog')}
title={window.i18n('reportIssue')}
description={window.i18n('shareBugDetails')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('surveyTitle')}
onClick={() => void shell.openExternal('https://getsession.org/survey')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('helpUsTranslateSession')}
onClick={() => void shell.openExternal('https://crowdin.com/project/session-desktop/')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('faq')}
onClick={() => void shell.openExternal('https://getsession.org/faq')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('support')}
onClick={() => void shell.openExternal('https://sessionapp.zendesk.com/hc/en-us')}
/>
</>
);
}
return null;
export const SettingsCategoryHelp = () => {
return (
<>
<SessionSettingButtonItem
onClick={() => {
ipcRenderer.send('show-debug-log');
}}
buttonShape={SessionButtonShape.Square}
buttonType={SessionButtonType.Solid}
buttonText={window.i18n('showDebugLog')}
title={window.i18n('reportIssue')}
description={window.i18n('shareBugDetails')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('surveyTitle')}
onClick={() => void shell.openExternal('https://getsession.org/survey')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('helpUsTranslateSession')}
onClick={() => void shell.openExternal('https://crowdin.com/project/session-desktop/')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('faq')}
onClick={() => void shell.openExternal('https://getsession.org/faq')}
/>
<SessionSettingsTitleWithLink
title={window.i18n('support')}
onClick={() => void shell.openExternal('https://sessionapp.zendesk.com/hc/en-us')}
/>
</>
);
};

@ -53,54 +53,51 @@ async function toggleStartInTray() {
}
}
export const SettingsCategoryPermissions = (props: { hasPassword: boolean | null }) => {
export const SettingsCategoryPermissions = () => {
const forceUpdate = useUpdate();
const isStartInTrayActive = Boolean(window.getSettingValue(SettingsKey.settingsStartInTray));
if (props.hasPassword !== null) {
return (
<>
<SessionToggleWithDescription
onClickToggle={async () => {
await window.toggleMediaPermissions();
forceUpdate();
}}
title={window.i18n('mediaPermissionsTitle')}
description={window.i18n('mediaPermissionsDescription')}
active={Boolean(window.getSettingValue('media-permissions'))}
dataTestId="enable-microphone"
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleCallMediaPermissions(forceUpdate);
forceUpdate();
}}
title={window.i18n('callMediaPermissionsTitle')}
description={window.i18n('callMediaPermissionsDescription')}
active={Boolean(window.getCallMediaPermissions())}
dataTestId="enable-calls"
/>
<SessionToggleWithDescription
onClickToggle={async () => {
const old = Boolean(window.getSettingValue(SettingsKey.settingsAutoUpdate));
await window.setSettingValue(SettingsKey.settingsAutoUpdate, !old);
forceUpdate();
}}
title={window.i18n('autoUpdateSettingTitle')}
description={window.i18n('autoUpdateSettingDescription')}
active={Boolean(window.getSettingValue(SettingsKey.settingsAutoUpdate))}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleStartInTray();
forceUpdate();
}}
title={window.i18n('startInTrayTitle')}
description={window.i18n('startInTrayDescription')}
active={isStartInTrayActive}
/>
</>
);
}
return null;
return (
<>
<SessionToggleWithDescription
onClickToggle={async () => {
await window.toggleMediaPermissions();
forceUpdate();
}}
title={window.i18n('mediaPermissionsTitle')}
description={window.i18n('mediaPermissionsDescription')}
active={Boolean(window.getSettingValue('media-permissions'))}
dataTestId="enable-microphone"
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleCallMediaPermissions(forceUpdate);
forceUpdate();
}}
title={window.i18n('callMediaPermissionsTitle')}
description={window.i18n('callMediaPermissionsDescription')}
active={Boolean(window.getCallMediaPermissions())}
dataTestId="enable-calls"
/>
<SessionToggleWithDescription
onClickToggle={async () => {
const old = Boolean(window.getSettingValue(SettingsKey.settingsAutoUpdate));
await window.setSettingValue(SettingsKey.settingsAutoUpdate, !old);
forceUpdate();
}}
title={window.i18n('autoUpdateSettingTitle')}
description={window.i18n('autoUpdateSettingDescription')}
active={Boolean(window.getSettingValue(SettingsKey.settingsAutoUpdate))}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
await toggleStartInTray();
forceUpdate();
}}
title={window.i18n('startInTrayTitle')}
description={window.i18n('startInTrayDescription')}
active={isStartInTrayActive}
/>
</>
);
};

@ -61,66 +61,66 @@ export const SettingsCategoryPrivacy = (props: {
const isLinkPreviewsOn = useHasLinkPreviewEnabled();
const areBlindedRequestsEnabled = useHasBlindedMsgRequestsEnabled();
if (props.hasPassword !== null) {
return (
<>
<SessionToggleWithDescription
onClickToggle={async () => {
const old = Boolean(window.getSettingValue(SettingsKey.settingsReadReceipt));
await window.setSettingValue(SettingsKey.settingsReadReceipt, !old);
forceUpdate();
}}
title={window.i18n('readReceiptSettingTitle')}
description={window.i18n('readReceiptSettingDescription')}
active={window.getSettingValue(SettingsKey.settingsReadReceipt)}
dataTestId="enable-read-receipts"
/>
<SessionToggleWithDescription
onClickToggle={async () => {
const old = Boolean(window.getSettingValue(SettingsKey.settingsTypingIndicator));
await window.setSettingValue(SettingsKey.settingsTypingIndicator, !old);
forceUpdate();
}}
title={window.i18n('typingIndicatorsSettingTitle')}
description={window.i18n('typingIndicatorsSettingDescription')}
active={Boolean(window.getSettingValue(SettingsKey.settingsTypingIndicator))}
childrenDescription={<TypingBubbleItem />}
/>
<SessionToggleWithDescription
onClickToggle={() => {
void toggleLinkPreviews(isLinkPreviewsOn, forceUpdate);
}}
title={window.i18n('linkPreviewsTitle')}
description={window.i18n('linkPreviewDescription')}
active={isLinkPreviewsOn}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
const toggledValue = !areBlindedRequestsEnabled;
await window.setSettingValue(SettingsKey.hasBlindedMsgRequestsEnabled, toggledValue);
await SessionUtilUserProfile.insertUserProfileIntoWrapper(
UserUtils.getOurPubKeyStrFromCache()
);
await ConfigurationSync.queueNewJobIfNeeded();
forceUpdate();
return (
<>
<SessionToggleWithDescription
onClickToggle={async () => {
const old = Boolean(window.getSettingValue(SettingsKey.settingsReadReceipt));
await window.setSettingValue(SettingsKey.settingsReadReceipt, !old);
forceUpdate();
}}
title={window.i18n('readReceiptSettingTitle')}
description={window.i18n('readReceiptSettingDescription')}
active={window.getSettingValue(SettingsKey.settingsReadReceipt)}
dataTestId="enable-read-receipts"
/>
<SessionToggleWithDescription
onClickToggle={async () => {
const old = Boolean(window.getSettingValue(SettingsKey.settingsTypingIndicator));
await window.setSettingValue(SettingsKey.settingsTypingIndicator, !old);
forceUpdate();
}}
title={window.i18n('typingIndicatorsSettingTitle')}
description={window.i18n('typingIndicatorsSettingDescription')}
active={Boolean(window.getSettingValue(SettingsKey.settingsTypingIndicator))}
childrenDescription={<TypingBubbleItem />}
/>
<SessionToggleWithDescription
onClickToggle={() => {
void toggleLinkPreviews(isLinkPreviewsOn, forceUpdate);
}}
title={window.i18n('linkPreviewsTitle')}
description={window.i18n('linkPreviewDescription')}
active={isLinkPreviewsOn}
/>
<SessionToggleWithDescription
onClickToggle={async () => {
const toggledValue = !areBlindedRequestsEnabled;
await window.setSettingValue(SettingsKey.hasBlindedMsgRequestsEnabled, toggledValue);
await SessionUtilUserProfile.insertUserProfileIntoWrapper(
UserUtils.getOurPubKeyStrFromCache()
);
await ConfigurationSync.queueNewJobIfNeeded();
forceUpdate();
}}
title={window.i18n('blindedMsgReqsSettingTitle')}
description={window.i18n('blindedMsgReqsSettingDesc')}
active={areBlindedRequestsEnabled}
/>
{!props.hasPassword ? (
<SessionSettingButtonItem
title={window.i18n('setAccountPasswordTitle')}
description={window.i18n('setAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('set', props.onPasswordUpdated);
}}
title={window.i18n('blindedMsgReqsSettingTitle')}
description={window.i18n('blindedMsgReqsSettingDesc')}
active={areBlindedRequestsEnabled}
buttonText={window.i18n('setPassword')}
dataTestId={'set-password-button'}
/>
{!props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('setAccountPasswordTitle')}
description={window.i18n('setAccountPasswordDescription')}
onClick={() => {
displayPasswordModal('set', props.onPasswordUpdated);
}}
buttonText={window.i18n('setPassword')}
dataTestId={'set-password-button'}
/>
)}
{props.hasPassword && (
) : (
<>
{/* We have a password, let's show the 'change' and 'remove' password buttons */}
<SessionSettingButtonItem
title={window.i18n('changeAccountPasswordTitle')}
description={window.i18n('changeAccountPasswordDescription')}
@ -130,8 +130,6 @@ export const SettingsCategoryPrivacy = (props: {
buttonText={window.i18n('changePassword')}
dataTestId="change-password-settings-button"
/>
)}
{props.hasPassword && (
<SessionSettingButtonItem
title={window.i18n('removeAccountPasswordTitle')}
description={window.i18n('removeAccountPasswordDescription')}
@ -142,9 +140,8 @@ export const SettingsCategoryPrivacy = (props: {
buttonText={window.i18n('removePassword')}
dataTestId="remove-password-settings-button"
/>
)}
</>
);
}
return null;
</>
)}
</>
);
};

Loading…
Cancel
Save