fix: since the pass hash is in the items table we can call it from storage

added storage function getPasswordHash and use everywhere, warn user to restart the app
pull/3083/head
William Grant 11 months ago
parent 268266d808
commit 59e6074429

@ -70,7 +70,7 @@
"changePassword": "Change Password", "changePassword": "Change Password",
"changePasswordInvalid": "The old password you entered is incorrect", "changePasswordInvalid": "The old password you entered is incorrect",
"changePasswordTitle": "Password Changed", "changePasswordTitle": "Password Changed",
"changePasswordToastDescription": "Your password has been changed. Please keep it safe.", "changePasswordToastDescription": "Your password has been changed. Please keep it safe and restart Session.",
"chooseAnAction": "Choose an action to start a conversation", "chooseAnAction": "Choose an action to start a conversation",
"classicDarkThemeTitle": "Classic Dark", "classicDarkThemeTitle": "Classic Dark",
"classicLightThemeTitle": "Classic Light", "classicLightThemeTitle": "Classic Light",
@ -440,7 +440,7 @@
"removePassword": "Remove Password", "removePassword": "Remove Password",
"removePasswordInvalid": "Incorrect password", "removePasswordInvalid": "Incorrect password",
"removePasswordTitle": "Password Removed", "removePasswordTitle": "Password Removed",
"removePasswordToastDescription": "Your password has been removed.", "removePasswordToastDescription": "Your password has been removed. Please restart Session.",
"removeResidueMembers": "Clicking ok will also remove those members as they left the group.", "removeResidueMembers": "Clicking ok will also remove those members as they left the group.",
"replyingToMessage": "Replying to:", "replyingToMessage": "Replying to:",
"replyToMessage": "Reply", "replyToMessage": "Reply",
@ -477,7 +477,7 @@
"setPasswordFail": "Failed to set password", "setPasswordFail": "Failed to set password",
"setPasswordInvalid": "Passwords do not match", "setPasswordInvalid": "Passwords do not match",
"setPasswordTitle": "Password Set", "setPasswordTitle": "Password Set",
"setPasswordToastDescription": "Your password has been set. Please keep it safe.", "setPasswordToastDescription": "Your password has been set. Please keep it safe and restart Session",
"settingAppliesToEveryone": "This setting applies to everyone in this conversation.", "settingAppliesToEveryone": "This setting applies to everyone in this conversation.",
"settingAppliesToYourMessages": "This setting applies to messages you send in this conversation.", "settingAppliesToYourMessages": "This setting applies to messages you send in this conversation.",
"settingsHeader": "Settings", "settingsHeader": "Settings",

@ -2,13 +2,13 @@
import autoBind from 'auto-bind'; import autoBind from 'auto-bind';
import { Component } from 'react'; import { Component } from 'react';
import { Data } from '../../data/data';
import { ToastUtils } from '../../session/utils'; import { ToastUtils } from '../../session/utils';
import { sessionPassword } from '../../state/ducks/modalDialog'; import { sessionPassword } from '../../state/ducks/modalDialog';
import { LocalizerKeys } from '../../types/LocalizerKeys'; import { LocalizerKeys } from '../../types/LocalizerKeys';
import type { PasswordAction } from '../../types/ReduxTypes'; import type { PasswordAction } from '../../types/ReduxTypes';
import { assertUnreachable } from '../../types/sqlSharedTypes'; import { assertUnreachable } from '../../types/sqlSharedTypes';
import { matchesHash, validatePassword } from '../../util/passwordUtils'; import { matchesHash, validatePassword } from '../../util/passwordUtils';
import { getPasswordHash } from '../../util/storage';
import { SessionWrapperModal } from '../SessionWrapperModal'; import { SessionWrapperModal } from '../SessionWrapperModal';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
import { SpacerSM } from '../basic/Text'; import { SpacerSM } from '../basic/Text';
@ -146,9 +146,9 @@ export class SessionSetPasswordDialog extends Component<Props, State> {
); );
} }
public async validatePasswordHash(password: string | null) { public validatePasswordHash(password: string | null) {
// Check if the password matches the hash we have stored // Check if the password matches the hash we have stored
const hash = await Data.getPasswordHash(); const hash = getPasswordHash();
if (hash && !matchesHash(password, hash)) { if (hash && !matchesHash(password, hash)) {
return false; return false;
} }
@ -224,7 +224,7 @@ export class SessionSetPasswordDialog extends Component<Props, State> {
return; return;
} }
const isValidWithStoredInDB = Boolean(await this.validatePasswordHash(oldPassword)); const isValidWithStoredInDB = this.validatePasswordHash(oldPassword);
if (!isValidWithStoredInDB) { if (!isValidWithStoredInDB) {
this.setState({ this.setState({
error: window.i18n('changePasswordInvalid'), error: window.i18n('changePasswordInvalid'),
@ -246,7 +246,7 @@ export class SessionSetPasswordDialog extends Component<Props, State> {
private async handleActionRemove(oldPassword: string) { private async handleActionRemove(oldPassword: string) {
// We don't validate oldPassword on change: this is validate on the validatePasswordHash below // We don't validate oldPassword on change: this is validate on the validatePasswordHash below
const isValidWithStoredInDB = Boolean(await this.validatePasswordHash(oldPassword)); const isValidWithStoredInDB = this.validatePasswordHash(oldPassword);
if (!isValidWithStoredInDB) { if (!isValidWithStoredInDB) {
this.setState({ this.setState({
error: window.i18n('removePasswordInvalid'), error: window.i18n('removePasswordInvalid'),
@ -279,7 +279,7 @@ export class SessionSetPasswordDialog extends Component<Props, State> {
return; return;
} }
const isValidWithStoredInDB = Boolean(await this.validatePasswordHash(enteredPassword)); const isValidWithStoredInDB = this.validatePasswordHash(enteredPassword);
if (!isValidWithStoredInDB) { if (!isValidWithStoredInDB) {
this.setState({ this.setState({
error: window.i18n('invalidPassword'), error: window.i18n('invalidPassword'),

@ -10,10 +10,10 @@ import { SessionIconButton } from '../icon';
import { SessionNotificationGroupSettings } from './SessionNotificationGroupSettings'; import { SessionNotificationGroupSettings } from './SessionNotificationGroupSettings';
import { Data } from '../../data/data';
import { sessionPassword } from '../../state/ducks/modalDialog'; import { sessionPassword } from '../../state/ducks/modalDialog';
import { SectionType, showLeftPaneSection } from '../../state/ducks/section'; import { SectionType, showLeftPaneSection } from '../../state/ducks/section';
import type { PasswordAction, SessionSettingCategory } from '../../types/ReduxTypes'; import type { PasswordAction, SessionSettingCategory } from '../../types/ReduxTypes';
import { getPasswordHash } from '../../util/storage';
import { SettingsCategoryAppearance } from './section/CategoryAppearance'; import { SettingsCategoryAppearance } from './section/CategoryAppearance';
import { CategoryConversations } from './section/CategoryConversations'; import { CategoryConversations } from './section/CategoryConversations';
import { SettingsCategoryHelp } from './section/CategoryHelp'; import { SettingsCategoryHelp } from './section/CategoryHelp';
@ -148,16 +148,8 @@ export const SessionSettingsView = (props: SettingsViewProps) => {
const [hasPassword, setHasPassword] = useState(true); const [hasPassword, setHasPassword] = useState(true);
useMount(() => { useMount(() => {
let isMounted = true; const hash = getPasswordHash();
// eslint-disable-next-line more/no-then setHasPassword(!!hash);
void Data.getPasswordHash().then(hash => {
if (isMounted) {
setHasPassword(!!hash);
}
});
return () => {
isMounted = false;
};
}); });
function onPasswordUpdated(action: string) { function onPasswordUpdated(action: string) {

@ -2,8 +2,8 @@ import { isEmpty } from 'lodash';
import { useState } from 'react'; import { useState } from 'react';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import useMount from 'react-use/lib/useMount'; import useMount from 'react-use/lib/useMount';
import { Data } from '../data/data';
import { updateEnterPasswordModal } from '../state/ducks/modalDialog'; import { updateEnterPasswordModal } from '../state/ducks/modalDialog';
import { getPasswordHash } from '../util/storage';
/** /**
* Password protection for a component if a password has been set * Password protection for a component if a password has been set
@ -27,15 +27,15 @@ export function usePasswordModal({
const dispatch = useDispatch(); const dispatch = useDispatch();
const validateAccess = async () => { const validateAccess = () => {
if (!isEmpty(passwordHash)) { if (!isEmpty(passwordHash)) {
return; return;
} }
const hash = await Data.getPasswordHash(); const hash = getPasswordHash();
setHasPassword(!!hash); setHasPassword(!!hash);
if (hash && !isEmpty(hash)) { if (hash) {
setPasswordHash(hash); setPasswordHash(hash);
dispatch( dispatch(
updateEnterPasswordModal({ updateEnterPasswordModal({
@ -63,7 +63,7 @@ export function usePasswordModal({
}; };
useMount(() => { useMount(() => {
void validateAccess(); validateAccess();
}); });
return { hasPassword, passwordValid }; return { hasPassword, passwordValid };

@ -1059,7 +1059,7 @@ ipc.on('set-password', async (event, passPhrase, oldPhrase) => {
return; return;
} }
if (_.isEmpty(passPhrase)) { if (isEmpty(passPhrase)) {
const defaultKey = getDefaultSQLKey(); const defaultKey = getDefaultSQLKey();
sqlNode.setSQLPassword(defaultKey); sqlNode.setSQLPassword(defaultKey);
sqlNode.removePasswordHash(); sqlNode.removePasswordHash();
@ -1070,7 +1070,6 @@ ipc.on('set-password', async (event, passPhrase, oldPhrase) => {
sqlNode.savePasswordHash(newHash); sqlNode.savePasswordHash(newHash);
userConfig.set('dbHasPassword', true); userConfig.set('dbHasPassword', true);
} }
sendResponse(undefined); sendResponse(undefined);
} catch (e) { } catch (e) {
const localisedError = locale.messages.setPasswordFail; const localisedError = locale.messages.setPasswordFail;

@ -93,6 +93,14 @@ function reset() {
items = Object.create(null); items = Object.create(null);
} }
function getBoolOrFalse(settingsKey: string): boolean {
const got = Storage.get(settingsKey, false);
if (isBoolean(got)) {
return got;
}
return false;
}
export async function setLocalPubKey(pubkey: string) { export async function setLocalPubKey(pubkey: string) {
await put('number_id', `${pubkey}.1`); await put('number_id', `${pubkey}.1`);
} }
@ -159,12 +167,8 @@ export async function saveRecentReations(reactions: Array<string>) {
return Storage.put('recent_reactions', reactions.join(' ')); return Storage.put('recent_reactions', reactions.join(' '));
} }
function getBoolOrFalse(settingsKey: string): boolean { export function getPasswordHash() {
const got = Storage.get(settingsKey, false); return Storage.get('passHash') as string;
if (isBoolean(got)) {
return got;
}
return false;
} }
export const Storage = { fetch, put, get, getBoolOrFalse, remove, onready, reset }; export const Storage = { fetch, put, get, getBoolOrFalse, remove, onready, reset };

Loading…
Cancel
Save