1
0
mirror of https://github.com/bitwarden/jslib synced 2026-01-03 00:53:13 +00:00

laptop issue

This commit is contained in:
addison
2021-11-26 20:37:55 -05:00
parent 907cb6b4ad
commit c527ce85e8
12 changed files with 127 additions and 127 deletions

View File

@@ -155,6 +155,7 @@ export class LockComponent implements OnInit {
}
const success = (await this.cryptoService.getKey(KeySuffixOptions.Biometric)) != null;
console.debug('unlockBiometric', success)
if (success) {
await this.doContinue();

View File

@@ -65,12 +65,12 @@ export abstract class StateService {
setConvertAccountToKeyConnector: (value: boolean, options?: StorageOptions) => Promise<void>;
getCryptoMasterKey: (options?: StorageOptions) => Promise<SymmetricCryptoKey>;
setCryptoMasterKey: (value: SymmetricCryptoKey, options?: StorageOptions) => Promise<void>;
getCryptoMasterKeyAuto: (options?: StorageOptions) => Promise<SymmetricCryptoKey>;
setCryptoMasterKeyAuto: (value: SymmetricCryptoKey, options?: StorageOptions) => Promise<void>;
getCryptoMasterKeyB64: (options: StorageOptions) => Promise<string>;
setCryptoMasterKeyB64: (value: string, options: StorageOptions) => Promise<void>;
getCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<SymmetricCryptoKey>;
setCryptoMasterKeyBiometric: (value: SymmetricCryptoKey, options?: StorageOptions) => Promise<void>;
getCryptoMasterKeyAuto: (options?: StorageOptions) => Promise<string>;
setCryptoMasterKeyAuto: (value: string, options?: StorageOptions) => Promise<void>;
getCryptoMasterKeyB64: (options?: StorageOptions) => Promise<string>;
setCryptoMasterKeyB64: (value: string, options?: StorageOptions) => Promise<void>;
getCryptoMasterKeyBiometric: (options?: StorageOptions) => Promise<string>;
setCryptoMasterKeyBiometric: (value: string, options?: StorageOptions) => Promise<void>;
getDecodedToken: (options?: StorageOptions) => Promise<any>;
setDecodedToken: (value: any, options?: StorageOptions) => Promise<void>;
getDecryptedCiphers: (options?: StorageOptions) => Promise<CipherView[]>;

View File

@@ -49,9 +49,9 @@ export class AccountData {
export class AccountKeys {
cryptoMasterKey: SymmetricCryptoKey;
cryptoMasterKeyAuto: SymmetricCryptoKey;
cryptoMasterKeyAuto: string;
cryptoMasterKeyB64: string;
cryptoMasterKeyBiometric: SymmetricCryptoKey;
cryptoMasterKeyBiometric: string;
cryptoSymmetricKey: EncryptionPair<string, SymmetricCryptoKey> = new EncryptionPair<string, SymmetricCryptoKey>();
organizationKeys: EncryptionPair<any, Map<string, SymmetricCryptoKey>> = new EncryptionPair<any, Map<string, SymmetricCryptoKey>>();
providerKeys: EncryptionPair<any, Map<string, SymmetricCryptoKey>> = new EncryptionPair<any, Map<string, SymmetricCryptoKey>>();
@@ -89,7 +89,6 @@ export class AccountSettings {
autoConfirmFingerPrints: boolean;
autoFillOnPageLoadDefault: boolean;
biometricLocked: boolean;
biometricText: string;
biometricUnlock: boolean;
clearClipboard: number;
defaultUriMatch: UriMatchType;
@@ -105,7 +104,6 @@ export class AccountSettings {
enableAlwaysOnTop: boolean;
enableAutoFillOnPageLoad: boolean;
enableBiometric: boolean;
enableBiometrics: boolean;
enableBrowserIntegration: boolean;
enableBrowserIntegrationFingerprint: boolean;
enableCloseToTray: boolean;
@@ -119,8 +117,6 @@ export class AccountSettings {
locale: string;
minimizeOnCopyToClipboard: boolean;
neverDomains: { [id: string]: any };
noAutoPromptBiometrics: boolean;
noAutoPromptBiometricsText: string;
openAtLogin: boolean;
passwordGenerationOptions: any;
pinProtected: EncryptionPair<string, EncString> = new EncryptionPair<string, EncString>();

View File

@@ -16,4 +16,8 @@ export class GlobalState {
vaultTimeoutAction: string;
loginRedirect: any;
mainWindowSize: number;
enableBiometrics: boolean;
biometricText: string;
noAutoPromptBiometrics: boolean;
noAutoPromptBiometricsText: string;
}

View File

@@ -6,4 +6,5 @@ export type StorageOptions = {
useSecureStorage?: boolean;
userId?: string;
htmlStorageLocation?: HtmlStorageLocation;
keySuffix?: string,
};

View File

@@ -87,10 +87,12 @@ export class CryptoService implements CryptoServiceAbstraction {
const inMemoryKey = await this.stateService.getCryptoMasterKey({ userId: userId });
if (inMemoryKey != null) {
console.debug('found another key. not clearing correctly on lock probably');
return inMemoryKey;
}
keySuffix ||= KeySuffixOptions.Auto;
console.debug('getKey', { keySuffix , key: await this.getKeyFromStorage(keySuffix, userId)});
const symmetricKey = await this.getKeyFromStorage(keySuffix, userId);
if (symmetricKey != null) {
@@ -103,7 +105,7 @@ export class CryptoService implements CryptoServiceAbstraction {
async getKeyFromStorage(keySuffix: KeySuffixOptions, userId?: string): Promise<SymmetricCryptoKey> {
const key = await this.retrieveKeyFromStorage(keySuffix, userId);
if (key != null) {
const symmetricKey = new SymmetricCryptoKey(Utils.fromB64ToArray(key.keyB64).buffer);
const symmetricKey = new SymmetricCryptoKey(Utils.fromB64ToArray(key).buffer);
if (!await this.validateKey(symmetricKey)) {
this.logService.warning('Wrong key, throwing away stored key');
@@ -345,8 +347,8 @@ export class CryptoService implements CryptoServiceAbstraction {
await this.stateService.setCryptoMasterKeyBiometric(null);
}
async clearKeyHash(): Promise<any> {
return await this.stateService.setKeyHash(null);
async clearKeyHash(userId?: string): Promise<any> {
return await this.stateService.setKeyHash(null, { userId: userId });
}
async clearEncKey(memoryOnly?: boolean, userId?: string): Promise<void> {
@@ -374,25 +376,25 @@ export class CryptoService implements CryptoServiceAbstraction {
}
}
async clearProviderKeys(memoryOnly?: boolean): Promise<void> {
await this.stateService.setDecryptedProviderKeys(null);
async clearProviderKeys(memoryOnly?: boolean, userId?: string): Promise<void> {
await this.stateService.setDecryptedProviderKeys(null, { userId: userId });
if (!memoryOnly) {
await this.stateService.setEncryptedProviderKeys(null);
await this.stateService.setEncryptedProviderKeys(null, { userId: userId });
}
}
async clearPinProtectedKey(): Promise<any> {
return await this.stateService.setDecryptedPinProtected(null);
async clearPinProtectedKey(userId?: string): Promise<any> {
return await this.stateService.setDecryptedPinProtected(null, { userId: userId });
}
async clearKeys(): Promise<any> {
await this.clearKey();
await this.clearKeyHash();
await this.clearOrgKeys();
await this.clearProviderKeys();
await this.clearEncKey();
await this.clearKeyPair();
await this.clearPinProtectedKey();
async clearKeys(userId?: string): Promise<any> {
await this.clearKey(true, userId);
await this.clearKeyHash(userId);
await this.clearOrgKeys(false, userId);
await this.clearProviderKeys(false, userId);
await this.clearEncKey(false, userId);
await this.clearKeyPair(false, userId);
await this.clearPinProtectedKey(userId);
}
async toggleKey(): Promise<any> {
@@ -694,7 +696,13 @@ export class CryptoService implements CryptoServiceAbstraction {
}
// Helpers
protected async storeKey(key: SymmetricCryptoKey, userId?: string) {
if (await this.shouldStoreKey(KeySuffixOptions.Auto, userId) || await this.shouldStoreKey(KeySuffixOptions.Biometric, userId)) {
await this.stateService.setCryptoMasterKeyB64(key.keyB64, { userId: userId });
} else {
await this.stateService.setCryptoMasterKeyB64(null, { userId: userId });
}
}
protected async shouldStoreKey(keySuffix: KeySuffixOptions, userId?: string) {
let shouldStoreKey = false;
@@ -862,25 +870,8 @@ export class CryptoService implements CryptoServiceAbstraction {
return [new SymmetricCryptoKey(encKey), encKeyEnc];
}
private async getSuffix(userId?: string): Promise<KeySuffixOptions> {
return await this.shouldStoreKey(KeySuffixOptions.Auto, userId) ?
KeySuffixOptions.Auto :
await this.shouldStoreKey(KeySuffixOptions.Biometric, userId) ?
KeySuffixOptions.Biometric :
null;
}
private async clearSecretKeyStore(userId?: string): Promise<void> {
await this.stateService.setCryptoMasterKeyAuto(null, { userId: userId });
await this.stateService.setCryptoMasterKeyBiometric(null, { userId: userId });
}
private async storeKey(key: SymmetricCryptoKey, userId?: string) {
const shouldStoreAuto = await this.shouldStoreKey(KeySuffixOptions.Auto, userId);
await this.stateService.setCryptoMasterKeyAuto(shouldStoreAuto ? key : null, { userId: userId });
const shouldStoreBiometric = await this.shouldStoreKey(KeySuffixOptions.Biometric, userId);
await this.stateService.setCryptoMasterKeyBiometric(shouldStoreBiometric ? key : null, { userId: userId });
}
}

View File

@@ -53,7 +53,16 @@ export class StateService implements StateServiceAbstraction {
if (await this.getActiveUserIdFromStorage() != null) {
const diskState = await this.storageService.get<State>('state', await this.defaultOnDiskOptions());
this.state = diskState;
await this.saveStateToStorage(diskState, await this.defaultOnDiskMemoryOptions());
// if (this.state.accounts != null && Object.keys(this.state.accounts).length > 0) {
// // Long term storage mechanisms may return undefined for nested account objects that we always want initilized
// // Reconstruct them here to ensure things like serverUrl are always accessible for all accounts
// for (const userId in this.state.accounts) {
// this.state.accounts[userId] = new Account(this.state.accounts[userId]);
// }
// }
await this.saveStateToStorage(this.state, await this.defaultOnDiskMemoryOptions());
}
}
@@ -177,19 +186,19 @@ export class StateService implements StateServiceAbstraction {
}
async setBiometricLocked(value: boolean, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
const account = await this.getAccount(this.reconcileOptions(options, this.defaultInMemoryOptions));
account.settings.biometricLocked = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
await this.saveAccount(account, this.reconcileOptions(options, this.defaultInMemoryOptions));
}
async getBiometricText(options?: StorageOptions): Promise<string> {
return (await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.settings?.biometricText;
return (await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.biometricText;
}
async setBiometricText(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
account.settings.biometricText = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
const globals = await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
globals.biometricText = value;
await this.saveGlobals(globals, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
}
async getBiometricUnlock(options?: StorageOptions): Promise<boolean> {
@@ -263,44 +272,47 @@ export class StateService implements StateServiceAbstraction {
async setCryptoMasterKey(value: SymmetricCryptoKey, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, this.defaultInMemoryOptions));
console.debug('setting crypto master key', {
email: account.profile.email,
requestedUserId: options?.userId,
requestedUserEmail: await this.getEmail({ userId: options?.userId }),
account: account,
vaule: value,
})
account.keys.cryptoMasterKey = value;
await this.saveAccount(account, this.reconcileOptions(options, this.defaultInMemoryOptions));
}
async getCryptoMasterKeyAuto(options?: StorageOptions): Promise<SymmetricCryptoKey> {
async getCryptoMasterKeyAuto(options?: StorageOptions): Promise<string> {
return (await this.getAccount(this.reconcileOptions(options, await this.defaultSecureStorageOptions())))?.keys?.cryptoMasterKeyAuto;
}
async setCryptoMasterKeyAuto(value: SymmetricCryptoKey, options?: StorageOptions): Promise<void> {
async setCryptoMasterKeyAuto(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
account.keys.cryptoMasterKeyAuto = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
}
async getCryptoMasterKeyB64(options: StorageOptions): Promise<string> {
async getCryptoMasterKeyB64(options?: StorageOptions): Promise<string> {
const value = (await this.getAccount(this.reconcileOptions(options, await this.defaultSecureStorageOptions())))?.keys?.cryptoMasterKeyB64;
return value;
}
async setCryptoMasterKeyB64(value: string, options: StorageOptions): Promise<void> {
try {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
if (account != null) {
account.keys.cryptoMasterKeyB64 = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
}
} catch (e) {
this.logService.error(e);
}
async setCryptoMasterKeyB64(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
account.keys.cryptoMasterKeyB64 = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
}
async getCryptoMasterKeyBiometric(options?: StorageOptions): Promise<SymmetricCryptoKey> {
async getCryptoMasterKeyBiometric(options?: StorageOptions): Promise<string> {
options = this.reconcileOptions(options, { keySuffix: 'biometric' })
return (await this.getAccount(this.reconcileOptions(options, await this.defaultSecureStorageOptions())))?.keys?.cryptoMasterKeyBiometric;
}
async setCryptoMasterKeyBiometric(value: SymmetricCryptoKey, options?: StorageOptions): Promise<void> {
async setCryptoMasterKeyBiometric(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
account.keys.cryptoMasterKeyBiometric = value;
console.debug('saving biometric key', value);
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultSecureStorageOptions()));
}
@@ -577,12 +589,12 @@ export class StateService implements StateServiceAbstraction {
}
async getEnableBiometric(options?: StorageOptions): Promise<boolean> {
return (await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.settings?.enableBiometrics ?? false;
return (await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.enableBiometrics ?? false;
}
async setEnableBiometric(value: boolean, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
account.settings.enableBiometrics = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
const globals = await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
globals.enableBiometrics = value;
await this.saveGlobals(globals, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
}
async getEnableBrowserIntegration(options?: StorageOptions): Promise<boolean> {
@@ -950,21 +962,21 @@ export class StateService implements StateServiceAbstraction {
}
async getNoAutoPromptBiometrics(options?: StorageOptions): Promise<boolean> {
return (await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.settings?.noAutoPromptBiometrics ?? false;
return (await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.noAutoPromptBiometrics ?? false;
}
async setNoAutoPromptBiometrics(value: boolean, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
account.settings.noAutoPromptBiometrics = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
const globals = await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
globals.noAutoPromptBiometrics = value;
await this.saveGlobals(globals, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
}
async getNoAutoPromptBiometricsText(options?: StorageOptions): Promise<string> {
return (await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.settings?.noAutoPromptBiometricsText;
return (await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions())))?.noAutoPromptBiometricsText;
}
async setNoAutoPromptBiometricsText(value: string, options?: StorageOptions): Promise<void> {
const account = await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
account.settings.noAutoPromptBiometricsText = value;
await this.saveAccount(account, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
const globals = await this.getGlobals(this.reconcileOptions(options, await this.defaultOnDiskOptions()));
globals.noAutoPromptBiometricsText = value;
await this.saveGlobals(globals, this.reconcileOptions(options, await this.defaultOnDiskOptions()));
}
async getOpenAtLogin(options?: StorageOptions): Promise<boolean> {
@@ -1339,30 +1351,9 @@ export class StateService implements StateServiceAbstraction {
private async pushAccounts(): Promise<void> {
if (this.state?.accounts == null || Object.keys(this.state.accounts).length < 1) {
this.accounts.next(null);
return;
}
for (const i in this.state.accounts) {
if (this.state.accounts[i]?.profile?.userId == null) {
continue;
}
if (this.state.accounts[i].profile.userId === this.state.activeUserId) {
this.state.accounts[i].profile.authenticationStatus = AuthenticationStatus.Active;
} else {
const vaultTimeout = await this.getVaultTimeout({
storageLocation: StorageLocation.Disk,
userId: this.state.accounts[i].profile.userId,
});
const lastActive = await this.getLastActive({
storageLocation: StorageLocation.Disk,
userId: this.state.accounts[i].profile.userId,
});
const diffSeconds = ((new Date()).getTime() - lastActive) / 1000;
this.state.accounts[i].profile.authenticationStatus = diffSeconds < (vaultTimeout * 60) ?
AuthenticationStatus.Unlocked :
AuthenticationStatus.Locked;
}
}
this.accounts.next(this.state.accounts);
}
@@ -1374,6 +1365,7 @@ export class StateService implements StateServiceAbstraction {
requestedOptions.storageLocation = requestedOptions?.storageLocation ?? defaultOptions.storageLocation;
requestedOptions.useSecureStorage = requestedOptions?.useSecureStorage ?? defaultOptions.useSecureStorage;
requestedOptions.htmlStorageLocation = requestedOptions?.htmlStorageLocation ?? defaultOptions.htmlStorageLocation;
requestedOptions.keySuffix = requestedOptions?.keySuffix ?? defaultOptions.keySuffix;
return requestedOptions;
}
@@ -1427,12 +1419,7 @@ export class StateService implements StateServiceAbstraction {
return;
}
state.accounts[userId] = new Account({
profile: state.accounts[userId].profile,
settings: state.accounts[userId].settings,
data: state.accounts[userId].data,
});
delete state.accounts[userId];
await this.saveStateToStorage(state, await this.defaultOnDiskLocalOptions());
}
@@ -1442,12 +1429,7 @@ export class StateService implements StateServiceAbstraction {
return;
}
state.accounts[userId] = new Account({
profile: state.accounts[userId].profile,
settings: state.accounts[userId].settings,
data: state.accounts[userId].data,
});
delete state.accounts[userId];
await this.saveStateToStorage(state, await this.defaultOnDiskOptions());
}
@@ -1456,15 +1438,13 @@ export class StateService implements StateServiceAbstraction {
if (state?.accounts[userId] == null) {
return;
}
state.accounts[userId] = null;
delete state.accounts[userId];
await this.secureStorageService.save('state', state);
}
private removeAccountFromMemory(userId: string = this.state.activeUserId): void {
if (this.state?.accounts[userId] == null) {
return;
}
delete this.state.accounts[userId ?? this.state.activeUserId];
delete this.state.accounts[userId];
}
private async saveStateToStorage(state: State, options: StorageOptions): Promise<void> {

View File

@@ -47,7 +47,7 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
const neverLock = await this.cryptoService.hasKeyStored(KeySuffixOptions.Auto, userId) &&
!(await this.stateService.getEverBeenUnlocked({ userId: userId }));
if (neverLock) {
// TODO: This also sets the key so when we check memory in the next line it finds a key.
// TODO: This also _sets_ the key so when we check memory in the next line it finds a key.
// We should refactor here.
await this.cryptoService.getKey(KeySuffixOptions.Auto, userId);
}
@@ -86,17 +86,20 @@ export class VaultTimeoutService implements VaultTimeoutServiceAbstraction {
this.searchService.clearIndex();
}
await this.folderService.clearCache(userId);
await this.cipherService.clearCache(userId);
await this.collectionService.clearCache(userId);
await this.stateService.setEverBeenUnlocked(true, { userId: userId });
await this.stateService.setBiometricLocked(true, { userId: userId });
await this.cryptoService.clearKey(false, userId);
await this.cryptoService.clearOrgKeys(true, userId);
await this.cryptoService.clearKeyPair(true, userId);
await this.cryptoService.clearEncKey(true, userId);
await this.stateService.setBiometricLocked(true, { userId: userId });
await this.folderService.clearCache(userId);
await this.cipherService.clearCache(userId);
await this.collectionService.clearCache(userId);
this.messagingService.send('locked', { userId: userId });
if (this.lockedCallback != null) {
await this.lockedCallback();
}

View File

@@ -17,6 +17,7 @@ export class KeytarStorageListener {
init() {
ipcMain.on('keytar', async (event: any, message: any) => {
try {
console.debug('recieved message', message);
let serviceName = this.serviceName;
message.keySuffix = '_' + (message.keySuffix ?? '');
if (message.keySuffix !== '_') {

View File

@@ -7,6 +7,7 @@ import { CryptoService } from 'jslib-common/services/crypto.service';
import { KeySuffixOptions } from 'jslib-common/enums/keySuffixOptions';
import { StorageLocation } from 'jslib-common/enums/storageLocation';
import { SymmetricCryptoKey } from 'jslib-common/models/domain/symmetricCryptoKey';
export class ElectronCryptoService extends CryptoService {
@@ -20,6 +21,20 @@ export class ElectronCryptoService extends CryptoService {
return super.hasKeyStored(keySuffix);
}
protected async storeKey(key: SymmetricCryptoKey, userId?: string) {
if (await this.shouldStoreKey(KeySuffixOptions.Auto, userId)) {
await this.stateService.setCryptoMasterKeyAuto(key.keyB64, { userId: userId });
} else {
this.clearStoredKey(KeySuffixOptions.Auto);
}
if (await this.shouldStoreKey(KeySuffixOptions.Biometric, userId)) {
await this.stateService.setCryptoMasterKeyBiometric(key.keyB64, { userId: userId });
} else {
this.clearStoredKey(KeySuffixOptions.Biometric);
}
}
protected async retrieveKeyFromStorage(keySuffix: KeySuffixOptions) {
await this.upgradeSecurelyStoredKey();
return super.retrieveKeyFromStorage(keySuffix);
@@ -31,7 +46,7 @@ export class ElectronCryptoService extends CryptoService {
*/
private async upgradeSecurelyStoredKey() {
// attempt key upgrade, but if we fail just delete it. Keys will be stored property upon unlock anyway.
const key = await this.stateService.getCryptoMasterKey({ storageLocation: StorageLocation.Disk, useSecureStorage: true });
const key = await this.stateService.getCryptoMasterKeyB64();
if (key == null) {
return;
@@ -49,6 +64,6 @@ export class ElectronCryptoService extends CryptoService {
this.logService.error(e);
}
await this.stateService.setCryptoMasterKey(null, { storageLocation: StorageLocation.Disk, useSecureStorage: true });
await this.stateService.setCryptoMasterKeyB64(null);
}
}

View File

@@ -9,6 +9,7 @@ export class ElectronRendererSecureStorageService implements StorageService {
const val = ipcRenderer.sendSync('keytar', {
action: 'getPassword',
key: key,
keySuffix: options?.keySuffix ?? '',
});
return Promise.resolve(val != null ? JSON.parse(val) as T : null);
}
@@ -17,6 +18,7 @@ export class ElectronRendererSecureStorageService implements StorageService {
const val = ipcRenderer.sendSync('keytar', {
action: 'hasPassword',
key: key,
keySuffix: options?.keySuffix ?? '',
});
return Promise.resolve(!!val);
}
@@ -25,6 +27,7 @@ export class ElectronRendererSecureStorageService implements StorageService {
ipcRenderer.sendSync('keytar', {
action: 'setPassword',
key: key,
keySuffix: options?.keySuffix ?? '',
value: JSON.stringify(obj),
});
return Promise.resolve();
@@ -34,6 +37,7 @@ export class ElectronRendererSecureStorageService implements StorageService {
ipcRenderer.sendSync('keytar', {
action: 'deletePassword',
key: key,
keySuffix: options?.keySuffix ?? '',
});
return Promise.resolve();
}

View File

@@ -25,8 +25,12 @@ export function isAppImage() {
return process.platform === 'linux' && 'APPIMAGE' in process.env;
}
export function isMac() {
return process.platform === 'darwin';
}
export function isMacAppStore() {
return process.platform === 'darwin' && process.mas && process.mas === true;
return isMac() && process.mas && process.mas === true;
}
export function isWindowsStore() {