1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-11 22:03:36 +00:00
Files
browser/libs/common/src/state-migrations/migrate.ts
Jonathan Prusik c65e92f769 [PM-5560] Implement Autofill Settings state provider (#7767)
* Begin migration of autofill settings

Co-authored-by: Cesar Gonzalez <cagonzalezcs@users.noreply.github.com>
Co-authored-by: Thomas Avery <Thomas-Avery@users.noreply.github.com>
Co-authored-by: Jonathan Prusik <jprusik@users.noreply.github.com>
Co-authored-by: Colton Hurst <coltonhurst@users.noreply.github.com>

* add browser dependency for AutofillSettingsService

Co-authored-by: Matt Gibson <mgibson@bitwarden.com>

* update autofill settings service

* replace usages of stateService get/set autofillOnPageLoad with autofillSettingsService

* replace usages of stateService get/set autofillOnPageLoadDefault with autofillSettingsService

* replace usages of stateService get/set autoCopyTotp with autofillSettingsService

* replace usages of stateService get/set autoFillOnPageLoadCalloutIsDismissed with autofillSettingsService

* replace usages of stateService get/set activateAutoFillOnPageLoadFromPolicy with autofillSettingsService

* replace usages of get/set autoFillOverlayVisibility with autofillSettingsService

* inlineMenuVisibility should use global state

* add the AutofillSettingsService to background scripts

* fix typing

* replace additional usages of get/set autoFillOverlayVisibility and disableAutoTotpCopy with autofillSettingsService equivalents

* replace additional usages of get/set autofillOnPageLoadDefault with autofillSettingsService equivalent

* replace additional usages of get/set activateAutoFillOnPageLoadFromPolicy with autofillSettingsService equivalent

* remove additional deprecated and unused state service calls

* improve naming conventions and consistency

* fix missing mock for policy service test

* replace missing overlay background tests

* cleanup

* fix double inversion

* fix reference to wrong setter

* move handleActivateAutofillPolicy out of BrowserPolicyService

* create state migration script

* resolve linting issues

* remove migrated setting properties

* add AutofillSettingsSErvice to jslib-services

* handle conditional content script loading via autofillOnPageLoad check

* add deprecated note to getFromLocalStorage

* add jsdoc decorators to new autofill service methods

* handle undefined globalState

* move autofill settings out of BrowserPolicyService

* Move autofill settings code out of policyService

* fix tests

* fix typo in state definition

---------

Co-authored-by: Matt Gibson <mgibson@bitwarden.com>
Co-authored-by: Cesar Gonzalez <cagonzalezcs@users.noreply.github.com>
Co-authored-by: Thomas Avery <Thomas-Avery@users.noreply.github.com>
Co-authored-by: Colton Hurst <coltonhurst@users.noreply.github.com>
Co-authored-by: Thomas Rittson <trittson@bitwarden.com>
2024-02-12 17:11:04 -05:00

125 lines
5.0 KiB
TypeScript

// eslint-disable-next-line import/no-restricted-paths -- Needed to print log messages
import { LogService } from "../platform/abstractions/log.service";
// eslint-disable-next-line import/no-restricted-paths -- Needed to interface with storage locations
import { AbstractStorageService } from "../platform/abstractions/storage.service";
import { MigrationBuilder } from "./migration-builder";
import { MigrationHelper } from "./migration-helper";
import { EverHadUserKeyMigrator } from "./migrations/10-move-ever-had-user-key-to-state-providers";
import { OrganizationKeyMigrator } from "./migrations/11-move-org-keys-to-state-providers";
import { MoveEnvironmentStateToProviders } from "./migrations/12-move-environment-state-to-providers";
import { ProviderKeyMigrator } from "./migrations/13-move-provider-keys-to-state-providers";
import { MoveBiometricClientKeyHalfToStateProviders } from "./migrations/14-move-biometric-client-key-half-state-to-providers";
import { FolderMigrator } from "./migrations/15-move-folder-state-to-state-provider";
import { LastSyncMigrator } from "./migrations/16-move-last-sync-to-state-provider";
import { EnablePasskeysMigrator } from "./migrations/17-move-enable-passkeys-to-state-providers";
import { AutofillSettingsKeyMigrator } from "./migrations/18-move-autofill-settings-to-state-providers";
import { FixPremiumMigrator } from "./migrations/3-fix-premium";
import { RemoveEverBeenUnlockedMigrator } from "./migrations/4-remove-ever-been-unlocked";
import { AddKeyTypeToOrgKeysMigrator } from "./migrations/5-add-key-type-to-org-keys";
import { RemoveLegacyEtmKeyMigrator } from "./migrations/6-remove-legacy-etm-key";
import { MoveBiometricAutoPromptToAccount } from "./migrations/7-move-biometric-auto-prompt-to-account";
import { MoveStateVersionMigrator } from "./migrations/8-move-state-version";
import { MoveBrowserSettingsToGlobal } from "./migrations/9-move-browser-settings-to-global";
import { MinVersionMigrator } from "./migrations/min-version";
export const MIN_VERSION = 2;
export const CURRENT_VERSION = 18;
export type MinVersion = typeof MIN_VERSION;
export async function migrate(
storageService: AbstractStorageService,
logService: LogService,
): Promise<void> {
const migrationHelper = new MigrationHelper(
await currentVersion(storageService, logService),
storageService,
logService,
);
if (migrationHelper.currentVersion < 0) {
// Cannot determine state, assuming empty so we don't repeatedly apply a migration.
await storageService.save("stateVersion", CURRENT_VERSION);
return;
}
await MigrationBuilder.create()
.with(MinVersionMigrator)
.with(FixPremiumMigrator, 2, 3)
.with(RemoveEverBeenUnlockedMigrator, 3, 4)
.with(AddKeyTypeToOrgKeysMigrator, 4, 5)
.with(RemoveLegacyEtmKeyMigrator, 5, 6)
.with(MoveBiometricAutoPromptToAccount, 6, 7)
.with(MoveStateVersionMigrator, 7, 8)
.with(MoveBrowserSettingsToGlobal, 8, 9)
.with(EverHadUserKeyMigrator, 9, 10)
.with(OrganizationKeyMigrator, 10, 11)
.with(MoveEnvironmentStateToProviders, 11, 12)
.with(ProviderKeyMigrator, 12, 13)
.with(MoveBiometricClientKeyHalfToStateProviders, 13, 14)
.with(FolderMigrator, 14, 15)
.with(LastSyncMigrator, 15, 16)
.with(EnablePasskeysMigrator, 16, 17)
.with(AutofillSettingsKeyMigrator, 17, CURRENT_VERSION)
.migrate(migrationHelper);
}
export async function currentVersion(
storageService: AbstractStorageService,
logService: LogService,
) {
let state = await storageService.get<number>("stateVersion");
if (state == null) {
// Pre v8
state = (await storageService.get<{ stateVersion: number }>("global"))?.stateVersion;
}
if (state == null) {
logService.info("No state version found, assuming empty state.");
return -1;
}
logService.info(`State version: ${state}`);
return state;
}
/**
* Waits for migrations to have a chance to run and will resolve the promise once they are.
*
* @param storageService Disk storage where the `stateVersion` will or is already saved in.
* @param logService Log service
*/
export async function waitForMigrations(
storageService: AbstractStorageService,
logService: LogService,
) {
const isReady = async () => {
const version = await currentVersion(storageService, logService);
// The saved version is what we consider the latest
// migrations should be complete
return version === CURRENT_VERSION;
};
const wait = async (time: number) => {
// Wait exponentially
const nextTime = time * 2;
if (nextTime > 8192) {
// Don't wait longer than ~8 seconds in a single wait,
// if the migrations still haven't happened. They aren't
// likely to.
return;
}
return new Promise<void>((resolve) => {
setTimeout(async () => {
if (!(await isReady())) {
logService.info(`Waiting for migrations to finish, waiting for ${nextTime}ms`);
await wait(nextTime);
}
resolve();
}, time);
});
};
if (!(await isReady())) {
// Wait for 2ms to start with
await wait(2);
}
}