mirror of
https://github.com/bitwarden/browser.git
synced 2025-02-23 02:31:26 +01:00
PM-5273 Initial migration work for localData
This commit is contained in:
parent
b17239595d
commit
60ac34182d
@ -571,6 +571,7 @@ export default class MainBackground {
|
|||||||
this.encryptService,
|
this.encryptService,
|
||||||
this.cipherFileUploadService,
|
this.cipherFileUploadService,
|
||||||
this.configService,
|
this.configService,
|
||||||
|
this.stateProvider,
|
||||||
);
|
);
|
||||||
this.folderService = new FolderService(
|
this.folderService = new FolderService(
|
||||||
this.cryptoService,
|
this.cryptoService,
|
||||||
|
@ -42,6 +42,7 @@ import {
|
|||||||
i18nServiceFactory,
|
i18nServiceFactory,
|
||||||
I18nServiceInitOptions,
|
I18nServiceInitOptions,
|
||||||
} from "../../../platform/background/service-factories/i18n-service.factory";
|
} from "../../../platform/background/service-factories/i18n-service.factory";
|
||||||
|
import { stateProviderFactory } from "../../../platform/background/service-factories/state-provider.factory";
|
||||||
import {
|
import {
|
||||||
stateServiceFactory,
|
stateServiceFactory,
|
||||||
StateServiceInitOptions,
|
StateServiceInitOptions,
|
||||||
@ -81,6 +82,7 @@ export function cipherServiceFactory(
|
|||||||
await encryptServiceFactory(cache, opts),
|
await encryptServiceFactory(cache, opts),
|
||||||
await cipherFileUploadServiceFactory(cache, opts),
|
await cipherFileUploadServiceFactory(cache, opts),
|
||||||
await configServiceFactory(cache, opts),
|
await configServiceFactory(cache, opts),
|
||||||
|
await stateProviderFactory(cache, opts),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -460,6 +460,7 @@ export class Main {
|
|||||||
this.encryptService,
|
this.encryptService,
|
||||||
this.cipherFileUploadService,
|
this.cipherFileUploadService,
|
||||||
this.configService,
|
this.configService,
|
||||||
|
this.stateProvider,
|
||||||
);
|
);
|
||||||
|
|
||||||
this.folderService = new FolderService(
|
this.folderService = new FolderService(
|
||||||
|
@ -344,6 +344,7 @@ import { ModalService } from "./modal.service";
|
|||||||
encryptService: EncryptService,
|
encryptService: EncryptService,
|
||||||
fileUploadService: CipherFileUploadServiceAbstraction,
|
fileUploadService: CipherFileUploadServiceAbstraction,
|
||||||
configService: ConfigServiceAbstraction,
|
configService: ConfigServiceAbstraction,
|
||||||
|
stateProvider: StateProvider,
|
||||||
) =>
|
) =>
|
||||||
new CipherService(
|
new CipherService(
|
||||||
cryptoService,
|
cryptoService,
|
||||||
@ -356,6 +357,7 @@ import { ModalService } from "./modal.service";
|
|||||||
encryptService,
|
encryptService,
|
||||||
fileUploadService,
|
fileUploadService,
|
||||||
configService,
|
configService,
|
||||||
|
stateProvider,
|
||||||
),
|
),
|
||||||
deps: [
|
deps: [
|
||||||
CryptoServiceAbstraction,
|
CryptoServiceAbstraction,
|
||||||
@ -368,6 +370,7 @@ import { ModalService } from "./modal.service";
|
|||||||
EncryptService,
|
EncryptService,
|
||||||
CipherFileUploadServiceAbstraction,
|
CipherFileUploadServiceAbstraction,
|
||||||
ConfigServiceAbstraction,
|
ConfigServiceAbstraction,
|
||||||
|
StateProvider,
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -62,3 +62,5 @@ export const AUTOFILL_SETTINGS_DISK_LOCAL = new StateDefinition("autofillSetting
|
|||||||
export const VAULT_FILTER_DISK = new StateDefinition("vaultFilter", "disk", {
|
export const VAULT_FILTER_DISK = new StateDefinition("vaultFilter", "disk", {
|
||||||
web: "disk-local",
|
web: "disk-local",
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export const LOCAL_DATA = new StateDefinition("localData", "disk", { web: "disk-local" });
|
||||||
|
@ -17,6 +17,7 @@ import { RequirePasswordOnStartMigrator } from "./migrations/19-migrate-require-
|
|||||||
import { PrivateKeyMigrator } from "./migrations/20-move-private-key-to-state-providers";
|
import { PrivateKeyMigrator } from "./migrations/20-move-private-key-to-state-providers";
|
||||||
import { CollectionMigrator } from "./migrations/21-move-collections-state-to-state-provider";
|
import { CollectionMigrator } from "./migrations/21-move-collections-state-to-state-provider";
|
||||||
import { CollapsedGroupingsMigrator } from "./migrations/22-move-collapsed-groupings-to-state-provider";
|
import { CollapsedGroupingsMigrator } from "./migrations/22-move-collapsed-groupings-to-state-provider";
|
||||||
|
import { LocalDataMigrator } from "./migrations/23-move-local-data-to-state-provider";
|
||||||
import { FixPremiumMigrator } from "./migrations/3-fix-premium";
|
import { FixPremiumMigrator } from "./migrations/3-fix-premium";
|
||||||
import { RemoveEverBeenUnlockedMigrator } from "./migrations/4-remove-ever-been-unlocked";
|
import { RemoveEverBeenUnlockedMigrator } from "./migrations/4-remove-ever-been-unlocked";
|
||||||
import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org-keys";
|
import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org-keys";
|
||||||
@ -27,7 +28,7 @@ import { MoveBrowserSettingsToGlobal } from "./migrations/9-move-browser-setting
|
|||||||
import { MinVersionMigrator } from "./migrations/min-version";
|
import { MinVersionMigrator } from "./migrations/min-version";
|
||||||
|
|
||||||
export const MIN_VERSION = 2;
|
export const MIN_VERSION = 2;
|
||||||
export const CURRENT_VERSION = 22;
|
export const CURRENT_VERSION = 23;
|
||||||
export type MinVersion = typeof MIN_VERSION;
|
export type MinVersion = typeof MIN_VERSION;
|
||||||
|
|
||||||
export function createMigrationBuilder() {
|
export function createMigrationBuilder() {
|
||||||
@ -52,7 +53,8 @@ export function createMigrationBuilder() {
|
|||||||
.with(RequirePasswordOnStartMigrator, 18, 19)
|
.with(RequirePasswordOnStartMigrator, 18, 19)
|
||||||
.with(PrivateKeyMigrator, 19, 20)
|
.with(PrivateKeyMigrator, 19, 20)
|
||||||
.with(CollectionMigrator, 20, 21)
|
.with(CollectionMigrator, 20, 21)
|
||||||
.with(CollapsedGroupingsMigrator, 21, CURRENT_VERSION);
|
.with(CollapsedGroupingsMigrator, 21, 22)
|
||||||
|
.with(LocalDataMigrator, 22, CURRENT_VERSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function currentVersion(
|
export async function currentVersion(
|
||||||
|
@ -0,0 +1,117 @@
|
|||||||
|
import { MockProxy } from "jest-mock-extended";
|
||||||
|
|
||||||
|
import { MigrationHelper } from "../migration-helper";
|
||||||
|
import { mockMigrationHelper } from "../migration-helper.spec";
|
||||||
|
|
||||||
|
import { LocalDataMigrator } from "./23-move-local-data-to-state-provider";
|
||||||
|
|
||||||
|
function exampleJSON() {
|
||||||
|
return {
|
||||||
|
global: {
|
||||||
|
otherStuff: "otherStuff1",
|
||||||
|
},
|
||||||
|
authenticatedAccounts: ["user-1", "user-2"],
|
||||||
|
"user-1": {
|
||||||
|
localData: [
|
||||||
|
{
|
||||||
|
"6865ba55-7966-4d63-b743-b12000d49631": {
|
||||||
|
lastUsedDate: 1708950970632,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"f895f099-6739-4cca-9d61-b12200d04bfa": {
|
||||||
|
lastUsedDate: 1709031916943,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"user-2": {
|
||||||
|
localData: {
|
||||||
|
"fce9e7bf-bb3d-4650-897f-b12300f43541": {
|
||||||
|
lastUsedDate: 1708950970632,
|
||||||
|
},
|
||||||
|
"ffb90bc2-a4ff-4571-b954-b12300f4207e": {
|
||||||
|
lastUsedDate: 1709031916943,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function rollbackJSON() {
|
||||||
|
return {
|
||||||
|
authenticatedAccounts: ["user-1", "user-2"],
|
||||||
|
"user-1": {
|
||||||
|
localdata: [
|
||||||
|
{
|
||||||
|
"6865ba55-7966-4d63-b743-b12000d49631": {
|
||||||
|
lastUsedDate: 1708950970632,
|
||||||
|
},
|
||||||
|
"f895f099-6739-4cca-9d61-b12200d04bfa": {
|
||||||
|
lastUsedDate: 1709031916943,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
"user-2": {
|
||||||
|
localdata: [
|
||||||
|
{
|
||||||
|
"fce9e7bf-bb3d-4650-897f-b12300f43541": {
|
||||||
|
lastUsedDate: 1708950970632,
|
||||||
|
},
|
||||||
|
"ffb90bc2-a4ff-4571-b954-b12300f4207e": {
|
||||||
|
lastUsedDate: 1709031916943,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("LocalDataMigrator", () => {
|
||||||
|
let helper: MockProxy<MigrationHelper>;
|
||||||
|
let sut: LocalDataMigrator;
|
||||||
|
const keyDefinitionLike = {
|
||||||
|
key: "local_data",
|
||||||
|
stateDefinition: {
|
||||||
|
name: "localData",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
describe("migrate", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
helper = mockMigrationHelper(exampleJSON(), 23);
|
||||||
|
sut = new LocalDataMigrator(22, 23);
|
||||||
|
});
|
||||||
|
|
||||||
|
it("should remove local data from all accounts", async () => {
|
||||||
|
await sut.migrate(helper);
|
||||||
|
expect(helper.set).toHaveBeenCalledWith("user-1", {
|
||||||
|
localData: [
|
||||||
|
{
|
||||||
|
"6865ba55-7966-4d63-b743-b12000d49631": {
|
||||||
|
lastUsedDate: 1708950970632,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"f895f099-6739-4cca-9d61-b12200d04bfa": {
|
||||||
|
lastUsedDate: 1709031916943,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("rollback", () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
helper = mockMigrationHelper(rollbackJSON(), 23);
|
||||||
|
sut = new LocalDataMigrator(22, 23);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(["user-1", "user-2"])("should null out new values", async (userId) => {
|
||||||
|
await sut.rollback(helper);
|
||||||
|
expect(helper.setToUser).toHaveBeenCalledWith(userId, keyDefinitionLike, null);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -0,0 +1,50 @@
|
|||||||
|
import { KeyDefinitionLike, MigrationHelper } from "../migration-helper";
|
||||||
|
import { Migrator } from "../migrator";
|
||||||
|
|
||||||
|
type ExpectedAccountType = {
|
||||||
|
[cipherId: string]: LocalData;
|
||||||
|
};
|
||||||
|
|
||||||
|
type LocalData = {
|
||||||
|
lastUsedDate?: number;
|
||||||
|
lastLaunched?: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
const LOCAL_DATA: KeyDefinitionLike = {
|
||||||
|
key: "local_data",
|
||||||
|
stateDefinition: {
|
||||||
|
name: "localData",
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export class LocalDataMigrator extends Migrator<22, 23> {
|
||||||
|
async migrate(helper: MigrationHelper): Promise<void> {
|
||||||
|
const accounts = await helper.getAccounts<ExpectedAccountType>();
|
||||||
|
async function migrateAccount(userId: string, account: ExpectedAccountType): Promise<void> {
|
||||||
|
const value = account?.localData;
|
||||||
|
if (value != null) {
|
||||||
|
await helper.setToUser(userId, LOCAL_DATA, value);
|
||||||
|
delete account.LocalData;
|
||||||
|
await helper.set(userId, account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([...accounts.map(({ userId, account }) => migrateAccount(userId, account))]);
|
||||||
|
}
|
||||||
|
|
||||||
|
async rollback(helper: MigrationHelper): Promise<void> {
|
||||||
|
const accounts = await helper.getAccounts<ExpectedAccountType>();
|
||||||
|
async function rollbackAccount(userId: string, account: ExpectedAccountType): Promise<void> {
|
||||||
|
const value = await helper.getFromUser(userId, LOCAL_DATA);
|
||||||
|
if (account) {
|
||||||
|
account.localData = Object.assign(account.localData ?? {}, {
|
||||||
|
localData: value,
|
||||||
|
});
|
||||||
|
await helper.set(userId, account);
|
||||||
|
}
|
||||||
|
await helper.setToUser(userId, LOCAL_DATA, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
await Promise.all([...accounts.map(({ userId, account }) => rollbackAccount(userId, account))]);
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,8 @@
|
|||||||
import { mock } from "jest-mock-extended";
|
import { mock } from "jest-mock-extended";
|
||||||
import { of } from "rxjs";
|
import { of } from "rxjs";
|
||||||
|
|
||||||
|
import { FakeAccountService, mockAccountServiceWith } from "../../../spec/fake-account-service";
|
||||||
|
import { FakeStateProvider } from "../../../spec/fake-state-provider";
|
||||||
import { makeStaticByteArray } from "../../../spec/utils";
|
import { makeStaticByteArray } from "../../../spec/utils";
|
||||||
import { ApiService } from "../../abstractions/api.service";
|
import { ApiService } from "../../abstractions/api.service";
|
||||||
import { SearchService } from "../../abstractions/search.service";
|
import { SearchService } from "../../abstractions/search.service";
|
||||||
@ -11,10 +13,12 @@ import { CryptoService } from "../../platform/abstractions/crypto.service";
|
|||||||
import { EncryptService } from "../../platform/abstractions/encrypt.service";
|
import { EncryptService } from "../../platform/abstractions/encrypt.service";
|
||||||
import { I18nService } from "../../platform/abstractions/i18n.service";
|
import { I18nService } from "../../platform/abstractions/i18n.service";
|
||||||
import { StateService } from "../../platform/abstractions/state.service";
|
import { StateService } from "../../platform/abstractions/state.service";
|
||||||
|
import { Utils } from "../../platform/misc/utils";
|
||||||
import { EncArrayBuffer } from "../../platform/models/domain/enc-array-buffer";
|
import { EncArrayBuffer } from "../../platform/models/domain/enc-array-buffer";
|
||||||
import { EncString } from "../../platform/models/domain/enc-string";
|
import { EncString } from "../../platform/models/domain/enc-string";
|
||||||
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
|
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
|
||||||
import { ContainerService } from "../../platform/services/container.service";
|
import { ContainerService } from "../../platform/services/container.service";
|
||||||
|
import { UserId } from "../../types/guid";
|
||||||
import { CipherKey, OrgKey } from "../../types/key";
|
import { CipherKey, OrgKey } from "../../types/key";
|
||||||
import { CipherFileUploadService } from "../abstractions/file-upload/cipher-file-upload.service";
|
import { CipherFileUploadService } from "../abstractions/file-upload/cipher-file-upload.service";
|
||||||
import { UriMatchType, FieldType } from "../enums";
|
import { UriMatchType, FieldType } from "../enums";
|
||||||
@ -94,6 +98,8 @@ const cipherData: CipherData = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
const mockUserId = Utils.newGuid() as UserId;
|
||||||
|
let accountService: FakeAccountService;
|
||||||
|
|
||||||
describe("Cipher Service", () => {
|
describe("Cipher Service", () => {
|
||||||
const cryptoService = mock<CryptoService>();
|
const cryptoService = mock<CryptoService>();
|
||||||
@ -106,6 +112,8 @@ describe("Cipher Service", () => {
|
|||||||
const searchService = mock<SearchService>();
|
const searchService = mock<SearchService>();
|
||||||
const encryptService = mock<EncryptService>();
|
const encryptService = mock<EncryptService>();
|
||||||
const configService = mock<ConfigServiceAbstraction>();
|
const configService = mock<ConfigServiceAbstraction>();
|
||||||
|
accountService = mockAccountServiceWith(mockUserId);
|
||||||
|
const stateProvider = new FakeStateProvider(accountService);
|
||||||
|
|
||||||
let cipherService: CipherService;
|
let cipherService: CipherService;
|
||||||
let cipherObj: Cipher;
|
let cipherObj: Cipher;
|
||||||
@ -127,6 +135,7 @@ describe("Cipher Service", () => {
|
|||||||
encryptService,
|
encryptService,
|
||||||
cipherFileUploadService,
|
cipherFileUploadService,
|
||||||
configService,
|
configService,
|
||||||
|
stateProvider,
|
||||||
);
|
);
|
||||||
|
|
||||||
cipherObj = new Cipher(cipherData);
|
cipherObj = new Cipher(cipherData);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { firstValueFrom } from "rxjs";
|
import { Observable, firstValueFrom } from "rxjs";
|
||||||
import { SemVer } from "semver";
|
import { SemVer } from "semver";
|
||||||
|
|
||||||
import { ApiService } from "../../abstractions/api.service";
|
import { ApiService } from "../../abstractions/api.service";
|
||||||
@ -20,12 +20,14 @@ import Domain from "../../platform/models/domain/domain-base";
|
|||||||
import { EncArrayBuffer } from "../../platform/models/domain/enc-array-buffer";
|
import { EncArrayBuffer } from "../../platform/models/domain/enc-array-buffer";
|
||||||
import { EncString } from "../../platform/models/domain/enc-string";
|
import { EncString } from "../../platform/models/domain/enc-string";
|
||||||
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
|
import { SymmetricCryptoKey } from "../../platform/models/domain/symmetric-crypto-key";
|
||||||
|
import { ActiveUserState, KeyDefinition, LOCAL_DATA, StateProvider } from "../../platform/state";
|
||||||
import { UserKey, OrgKey } from "../../types/key";
|
import { UserKey, OrgKey } from "../../types/key";
|
||||||
import { CipherService as CipherServiceAbstraction } from "../abstractions/cipher.service";
|
import { CipherService as CipherServiceAbstraction } from "../abstractions/cipher.service";
|
||||||
import { CipherFileUploadService } from "../abstractions/file-upload/cipher-file-upload.service";
|
import { CipherFileUploadService } from "../abstractions/file-upload/cipher-file-upload.service";
|
||||||
import { FieldType, UriMatchType } from "../enums";
|
import { FieldType, UriMatchType } from "../enums";
|
||||||
import { CipherType } from "../enums/cipher-type";
|
import { CipherType } from "../enums/cipher-type";
|
||||||
import { CipherData } from "../models/data/cipher.data";
|
import { CipherData } from "../models/data/cipher.data";
|
||||||
|
import { LocalData } from "../models/data/local.data";
|
||||||
import { Attachment } from "../models/domain/attachment";
|
import { Attachment } from "../models/domain/attachment";
|
||||||
import { Card } from "../models/domain/card";
|
import { Card } from "../models/domain/card";
|
||||||
import { Cipher } from "../models/domain/cipher";
|
import { Cipher } from "../models/domain/cipher";
|
||||||
@ -54,11 +56,21 @@ import { PasswordHistoryView } from "../models/view/password-history.view";
|
|||||||
|
|
||||||
const CIPHER_KEY_ENC_MIN_SERVER_VER = new SemVer("2024.2.0");
|
const CIPHER_KEY_ENC_MIN_SERVER_VER = new SemVer("2024.2.0");
|
||||||
|
|
||||||
|
const LOCAL_DATA_KEY = new KeyDefinition<Record<string, LocalData>>(LOCAL_DATA, "local_data", {
|
||||||
|
deserializer: (obj) => obj,
|
||||||
|
});
|
||||||
|
|
||||||
export class CipherService implements CipherServiceAbstraction {
|
export class CipherService implements CipherServiceAbstraction {
|
||||||
private sortedCiphersCache: SortedCiphersCache = new SortedCiphersCache(
|
private sortedCiphersCache: SortedCiphersCache = new SortedCiphersCache(
|
||||||
this.sortCiphersByLastUsed,
|
this.sortCiphersByLastUsed,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
localData$: Observable<Record<string, LocalData>>;
|
||||||
|
|
||||||
|
private localDataState: ActiveUserState<Record<string, LocalData>>;
|
||||||
|
|
||||||
|
private stateProviderFlag: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private cryptoService: CryptoService,
|
private cryptoService: CryptoService,
|
||||||
private settingsService: SettingsService,
|
private settingsService: SettingsService,
|
||||||
@ -70,7 +82,15 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
private encryptService: EncryptService,
|
private encryptService: EncryptService,
|
||||||
private cipherFileUploadService: CipherFileUploadService,
|
private cipherFileUploadService: CipherFileUploadService,
|
||||||
private configService: ConfigServiceAbstraction,
|
private configService: ConfigServiceAbstraction,
|
||||||
) {}
|
private stateProvider: StateProvider,
|
||||||
|
) {
|
||||||
|
this.localDataState = this.stateProvider.getActive(LOCAL_DATA_KEY);
|
||||||
|
|
||||||
|
this.localData$ = this.localDataState.state$;
|
||||||
|
|
||||||
|
//TODO remove this before opening the PR and references to 5273
|
||||||
|
this.stateProviderFlag = false;
|
||||||
|
}
|
||||||
|
|
||||||
async getDecryptedCipherCache(): Promise<CipherView[]> {
|
async getDecryptedCipherCache(): Promise<CipherView[]> {
|
||||||
const decryptedCiphers = await this.stateService.getDecryptedCiphers();
|
const decryptedCiphers = await this.stateService.getDecryptedCiphers();
|
||||||
@ -266,11 +286,19 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const localData = await this.stateService.getLocalData();
|
//5273
|
||||||
|
let localData;
|
||||||
|
if (this.stateProviderFlag) {
|
||||||
|
localData = await firstValueFrom(this.localData$);
|
||||||
|
} else {
|
||||||
|
localData = await this.stateService.getLocalData();
|
||||||
|
}
|
||||||
|
|
||||||
return new Cipher(ciphers[id], localData ? localData[id] : null);
|
return new Cipher(ciphers[id], localData ? localData[id] : null);
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAll(): Promise<Cipher[]> {
|
async getAll(): Promise<Cipher[]> {
|
||||||
|
//const localData = await firstValueFrom(this.localData$);
|
||||||
const localData = await this.stateService.getLocalData();
|
const localData = await this.stateService.getLocalData();
|
||||||
const ciphers = await this.stateService.getEncryptedCiphers();
|
const ciphers = await this.stateService.getEncryptedCiphers();
|
||||||
const response: Cipher[] = [];
|
const response: Cipher[] = [];
|
||||||
@ -437,7 +465,14 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateLastUsedDate(id: string): Promise<void> {
|
async updateLastUsedDate(id: string): Promise<void> {
|
||||||
let ciphersLocalData = await this.stateService.getLocalData();
|
//5273
|
||||||
|
let ciphersLocalData: { [cipherId: string]: LocalData } | Record<string, LocalData>;
|
||||||
|
if (this.stateProviderFlag) {
|
||||||
|
ciphersLocalData = await firstValueFrom(this.localData$);
|
||||||
|
} else {
|
||||||
|
ciphersLocalData = await this.stateService.getLocalData();
|
||||||
|
}
|
||||||
|
|
||||||
if (!ciphersLocalData) {
|
if (!ciphersLocalData) {
|
||||||
ciphersLocalData = {};
|
ciphersLocalData = {};
|
||||||
}
|
}
|
||||||
@ -450,7 +485,12 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.stateService.setLocalData(ciphersLocalData);
|
//5273
|
||||||
|
if (this.stateProviderFlag) {
|
||||||
|
await this.localDataState.update(() => ciphersLocalData);
|
||||||
|
} else {
|
||||||
|
await this.stateService.setLocalData(ciphersLocalData);
|
||||||
|
}
|
||||||
|
|
||||||
const decryptedCipherCache = await this.stateService.getDecryptedCiphers();
|
const decryptedCipherCache = await this.stateService.getDecryptedCiphers();
|
||||||
if (!decryptedCipherCache) {
|
if (!decryptedCipherCache) {
|
||||||
@ -468,7 +508,14 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async updateLastLaunchedDate(id: string): Promise<void> {
|
async updateLastLaunchedDate(id: string): Promise<void> {
|
||||||
let ciphersLocalData = await this.stateService.getLocalData();
|
//5273
|
||||||
|
let ciphersLocalData: { [cipherId: string]: LocalData } | Record<string, LocalData>;
|
||||||
|
if (this.stateProviderFlag) {
|
||||||
|
ciphersLocalData = await firstValueFrom(this.localData$);
|
||||||
|
} else {
|
||||||
|
ciphersLocalData = await this.stateService.getLocalData();
|
||||||
|
}
|
||||||
|
|
||||||
if (!ciphersLocalData) {
|
if (!ciphersLocalData) {
|
||||||
ciphersLocalData = {};
|
ciphersLocalData = {};
|
||||||
}
|
}
|
||||||
@ -481,7 +528,12 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
await this.stateService.setLocalData(ciphersLocalData);
|
//5273
|
||||||
|
if (this.stateProviderFlag) {
|
||||||
|
await this.localDataState.update(() => ciphersLocalData);
|
||||||
|
} else {
|
||||||
|
await this.stateService.setLocalData(ciphersLocalData);
|
||||||
|
}
|
||||||
|
|
||||||
const decryptedCipherCache = await this.stateService.getDecryptedCiphers();
|
const decryptedCipherCache = await this.stateService.getDecryptedCiphers();
|
||||||
if (!decryptedCipherCache) {
|
if (!decryptedCipherCache) {
|
||||||
|
Loading…
Reference in New Issue
Block a user