mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 07:43:35 +00:00
[PM-5273] Migrate state in CipherService (#8314)
* PM-5273 Initial migration work for localData
* PM-5273 Encrypted and Decrypted ciphers migration to state provider
* pm-5273 Update references
* pm5273 Ensure prototype on cipher
* PM-5273 Add CipherId
* PM-5273 Remove migrated methods and updated references
* pm-5273 Fix versions
* PM-5273 Added missing options
* Conflict resolution
* Revert "Conflict resolution"
This reverts commit 0c0c2039ed.
* PM-5273 Fix PR comments
* Pm-5273 Fix comments
* PM-5273 Changed decryptedCiphers to use ActiveUserState
* PM-5273 Fix tests
* PM-5273 Fix pr comments
This commit is contained in:
@@ -9,10 +9,6 @@ import { GeneratorOptions } from "../../tools/generator/generator-options";
|
||||
import { GeneratedPasswordHistory, PasswordGeneratorOptions } from "../../tools/generator/password";
|
||||
import { UsernameGeneratorOptions } from "../../tools/generator/username";
|
||||
import { UserId } from "../../types/guid";
|
||||
import { CipherData } from "../../vault/models/data/cipher.data";
|
||||
import { LocalData } from "../../vault/models/data/local.data";
|
||||
import { CipherView } from "../../vault/models/view/cipher.view";
|
||||
import { AddEditCipherInfo } from "../../vault/types/add-edit-cipher-info";
|
||||
import { EnvironmentService } from "../abstractions/environment.service";
|
||||
import { LogService } from "../abstractions/log.service";
|
||||
import {
|
||||
@@ -221,34 +217,6 @@ export class StateService<
|
||||
return currentUser as UserId;
|
||||
}
|
||||
|
||||
async getAddEditCipherInfo(options?: StorageOptions): Promise<AddEditCipherInfo> {
|
||||
const account = await this.getAccount(
|
||||
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
|
||||
);
|
||||
// ensure prototype on cipher
|
||||
const raw = account?.data?.addEditCipherInfo;
|
||||
return raw == null
|
||||
? null
|
||||
: {
|
||||
cipher:
|
||||
raw?.cipher.toJSON != null
|
||||
? raw.cipher
|
||||
: CipherView.fromJSON(raw?.cipher as Jsonify<CipherView>),
|
||||
collectionIds: raw?.collectionIds,
|
||||
};
|
||||
}
|
||||
|
||||
async setAddEditCipherInfo(value: AddEditCipherInfo, options?: StorageOptions): Promise<void> {
|
||||
const account = await this.getAccount(
|
||||
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
|
||||
);
|
||||
account.data.addEditCipherInfo = value;
|
||||
await this.saveAccount(
|
||||
account,
|
||||
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* user key when using the "never" option of vault timeout
|
||||
*/
|
||||
@@ -465,24 +433,6 @@ export class StateService<
|
||||
await this.saveSecureStorageKey(partialKeys.biometricKey, value, options);
|
||||
}
|
||||
|
||||
@withPrototypeForArrayMembers(CipherView, CipherView.fromJSON)
|
||||
async getDecryptedCiphers(options?: StorageOptions): Promise<CipherView[]> {
|
||||
return (
|
||||
await this.getAccount(this.reconcileOptions(options, await this.defaultInMemoryOptions()))
|
||||
)?.data?.ciphers?.decrypted;
|
||||
}
|
||||
|
||||
async setDecryptedCiphers(value: CipherView[], options?: StorageOptions): Promise<void> {
|
||||
const account = await this.getAccount(
|
||||
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
|
||||
);
|
||||
account.data.ciphers.decrypted = value;
|
||||
await this.saveAccount(
|
||||
account,
|
||||
this.reconcileOptions(options, await this.defaultInMemoryOptions()),
|
||||
);
|
||||
}
|
||||
|
||||
@withPrototypeForArrayMembers(GeneratedPasswordHistory)
|
||||
async getDecryptedPasswordGenerationHistory(
|
||||
options?: StorageOptions,
|
||||
@@ -621,27 +571,6 @@ export class StateService<
|
||||
);
|
||||
}
|
||||
|
||||
@withPrototypeForObjectValues(CipherData)
|
||||
async getEncryptedCiphers(options?: StorageOptions): Promise<{ [id: string]: CipherData }> {
|
||||
return (
|
||||
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskMemoryOptions()))
|
||||
)?.data?.ciphers?.encrypted;
|
||||
}
|
||||
|
||||
async setEncryptedCiphers(
|
||||
value: { [id: string]: CipherData },
|
||||
options?: StorageOptions,
|
||||
): Promise<void> {
|
||||
const account = await this.getAccount(
|
||||
this.reconcileOptions(options, await this.defaultOnDiskMemoryOptions()),
|
||||
);
|
||||
account.data.ciphers.encrypted = value;
|
||||
await this.saveAccount(
|
||||
account,
|
||||
this.reconcileOptions(options, await this.defaultOnDiskMemoryOptions()),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Use UserKey instead
|
||||
*/
|
||||
@@ -805,26 +734,6 @@ export class StateService<
|
||||
);
|
||||
}
|
||||
|
||||
async getLocalData(options?: StorageOptions): Promise<{ [cipherId: string]: LocalData }> {
|
||||
return (
|
||||
await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()))
|
||||
)?.data?.localData;
|
||||
}
|
||||
|
||||
async setLocalData(
|
||||
value: { [cipherId: string]: LocalData },
|
||||
options?: StorageOptions,
|
||||
): Promise<void> {
|
||||
const account = await this.getAccount(
|
||||
this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()),
|
||||
);
|
||||
account.data.localData = value;
|
||||
await this.saveAccount(
|
||||
account,
|
||||
this.reconcileOptions(options, await this.defaultOnDiskLocalOptions()),
|
||||
);
|
||||
}
|
||||
|
||||
async getMinimizeOnCopyToClipboard(options?: StorageOptions): Promise<boolean> {
|
||||
return (
|
||||
(await this.getAccount(this.reconcileOptions(options, await this.defaultOnDiskOptions())))
|
||||
@@ -1510,50 +1419,3 @@ function withPrototypeForArrayMembers<T>(
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
function withPrototypeForObjectValues<T>(
|
||||
valuesConstructor: new (...args: any[]) => T,
|
||||
valuesConverter: (input: any) => T = (i) => i,
|
||||
): (
|
||||
target: any,
|
||||
propertyKey: string | symbol,
|
||||
descriptor: PropertyDescriptor,
|
||||
) => { value: (...args: any[]) => Promise<{ [key: string]: T }> } {
|
||||
return (target: any, propertyKey: string | symbol, descriptor: PropertyDescriptor) => {
|
||||
const originalMethod = descriptor.value;
|
||||
|
||||
return {
|
||||
value: function (...args: any[]) {
|
||||
const originalResult: Promise<{ [key: string]: T }> = originalMethod.apply(this, args);
|
||||
|
||||
if (!Utils.isPromise(originalResult)) {
|
||||
throw new Error(
|
||||
`Error applying prototype to stored value -- result is not a promise for method ${String(
|
||||
propertyKey,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
|
||||
return originalResult.then((result) => {
|
||||
if (result == null) {
|
||||
return null;
|
||||
} else {
|
||||
for (const [key, val] of Object.entries(result)) {
|
||||
result[key] =
|
||||
val == null || val.constructor.name === valuesConstructor.prototype.constructor.name
|
||||
? valuesConverter(val)
|
||||
: valuesConverter(
|
||||
Object.create(
|
||||
valuesConstructor.prototype,
|
||||
Object.getOwnPropertyDescriptors(val),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return result as { [key: string]: T };
|
||||
}
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user