All: Add support for single master password, to simplify handling of multiple encryption keys

This commit is contained in:
Laurent Cozic committed 2021-08-30 14:15:35 +01:00
1 parent 596f679b1f
commit ce89ee5bab
13 files changed
+295 -48

No files matched your search

@@ -8,6 +8,7 @@ import shim from '../../shim';
import { MasterKeyEntity } from '../../services/e2ee/types';
import time from '../../time';
import { masterKeyEnabled, setMasterKeyEnabled } from '../../services/synchronizer/syncInfoUtils';
import { findMasterKeyPassword } from '../../services/e2ee/utils';
class Shared {
@@ -16,12 +17,16 @@ class Shared {
public initialize(comp: any, props: any) {
comp.state = {
passwordChecks: {},
// Master keys that can be decrypted with the master password
// (normally all of them, but for legacy support we need this).
masterPasswordKeys: {},
stats: {
encrypted: null,
total: null,
},
passwords: Object.assign({}, props.passwords),
showDisabledMasterKeys: false,
masterPasswordInput: '',
};
comp.isMounted_ = false;
@@ -108,15 +113,37 @@ class Shared {
}
}
public async masterPasswordIsValid(comp: any, masterPassword: string = null) {
const activeMasterKey = comp.props.masterKeys.find((mk: MasterKeyEntity) => mk.id === comp.props.activeMasterKeyId);
masterPassword = masterPassword === null ? comp.props.masterPassword : masterPassword;
if (activeMasterKey && masterPassword) {
return EncryptionService.instance().checkMasterKeyPassword(activeMasterKey, masterPassword);
}
return false;
}
public async checkPasswords(comp: any) {
const passwordChecks = Object.assign({}, comp.state.passwordChecks);
const masterPasswordKeys = Object.assign({}, comp.state.masterPasswordKeys);
for (let i = 0; i < comp.props.masterKeys.length; i++) {
const mk = comp.props.masterKeys[i];
const password = comp.state.passwords[mk.id];
const password = await findMasterKeyPassword(EncryptionService.instance(), mk);
const ok = password ? await EncryptionService.instance().checkMasterKeyPassword(mk, password) : false;
passwordChecks[mk.id] = ok;
masterPasswordKeys[mk.id] = password === comp.props.masterPassword;
}
comp.setState({ passwordChecks: passwordChecks });
passwordChecks['master'] = await this.masterPasswordIsValid(comp);
comp.setState({ passwordChecks, masterPasswordKeys });
}
public masterPasswordStatus(comp: any) {
// Don't translate for now because that's temporary - later it should
// always be set and the label should be replaced by a "Change master
// password" button.
return comp.props.masterPassword ? 'Master password is set' : 'Master password is not set';
}
public decryptedStatText(comp: any) {
@@ -138,6 +165,14 @@ class Shared {
comp.checkPasswords();
}
public onMasterPasswordChange(comp: any, value: string) {
comp.setState({ masterPasswordInput: value });
}
public onMasterPasswordSave(comp: any) {
Setting.setValue('encryption.masterPassword', comp.state.masterPasswordInput);
}
public onPasswordChange(comp: any, mk: MasterKeyEntity, password: string) {
const passwords = Object.assign({}, comp.state.passwords);
passwords[mk.id] = password;