1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-19 17:53:39 +00:00
Files
browser/libs/common/src/state-migrations/migrations/14-move-biometric-client-key-half-state-to-providers.ts
Matt Gibson 414ee2563f [PM-5537] Biometric State Service (#7761)
* Create state for biometric client key halves

* Move enc string util to central utils

* Provide biometric state through service

* Use biometric state to track client key half

* Create migration for client key half

* Ensure client key half is removed on logout

* Remove account data for client key half

* Remove unnecessary key definition likes

* Remove moved state from account

* Fix null-conditional operator failure

* Simplify migration

* Remove lame test

* Fix test type

* Add migrator

* Prefer userKey when legacy not needed

* Fix tests
2024-02-05 13:02:28 -05:00

66 lines
2.1 KiB
TypeScript

import { KeyDefinitionLike, MigrationHelper } from "../migration-helper";
import { Migrator } from "../migrator";
type ExpectedAccountType = {
settings?: {
disableAutoBiometricsPrompt?: boolean;
biometricUnlock?: boolean;
dismissedBiometricRequirePasswordOnStartCallout?: boolean;
};
keys?: { biometricEncryptionClientKeyHalf?: string };
};
// Biometric text, no auto prompt text, fingerprint validated, and prompt cancelled are refreshed on every app start, so we don't need to migrate them
export const CLIENT_KEY_HALF: KeyDefinitionLike = {
key: "clientKeyHalf",
stateDefinition: { name: "biometricSettings" },
};
export class MoveBiometricClientKeyHalfToStateProviders extends Migrator<13, 14> {
async migrate(helper: MigrationHelper): Promise<void> {
const legacyAccounts = await helper.getAccounts<ExpectedAccountType>();
await Promise.all(
legacyAccounts.map(async ({ userId, account }) => {
// Move account data
if (account?.keys?.biometricEncryptionClientKeyHalf != null) {
await helper.setToUser(
userId,
CLIENT_KEY_HALF,
account.keys.biometricEncryptionClientKeyHalf,
);
// Delete old account data
delete account?.keys?.biometricEncryptionClientKeyHalf;
await helper.set(userId, account);
}
}),
);
}
async rollback(helper: MigrationHelper): Promise<void> {
async function rollbackUser(userId: string, account: ExpectedAccountType) {
let updatedAccount = false;
const userKeyHalf = await helper.getFromUser<string>(userId, CLIENT_KEY_HALF);
if (userKeyHalf) {
account ??= {};
account.keys ??= {};
updatedAccount = true;
account.keys.biometricEncryptionClientKeyHalf = userKeyHalf;
await helper.setToUser(userId, CLIENT_KEY_HALF, null);
}
if (updatedAccount) {
await helper.set(userId, account);
}
}
const accounts = await helper.getAccounts<ExpectedAccountType>();
await Promise.all(accounts.map(({ userId, account }) => rollbackUser(userId, account)));
}
}