mirror of
https://github.com/bitwarden/browser
synced 2025-12-17 08:43:33 +00:00
[PM-5559] Implement User Notification Settings state provider (#8032)
* create user notification settings state provider * replace state service get/set disableAddLoginNotification and disableChangedPasswordNotification with user notification settings service equivalents * migrate disableAddLoginNotification and disableChangedPasswordNotification global settings to user notification settings state provider * add content script messaging the background for enableChangedPasswordPrompt setting * Implementing feedback to provide on PR * Implementing feedback to provide on PR * PR suggestions cleanup --------- Co-authored-by: Cesar Gonzalez <cgonzalez@bitwarden.com>
This commit is contained in:
@@ -23,6 +23,7 @@ import { ClearClipboardDelayMigrator } from "./migrations/25-move-clear-clipboar
|
||||
import { RevertLastSyncMigrator } from "./migrations/26-revert-move-last-sync-to-state-provider";
|
||||
import { BadgeSettingsMigrator } from "./migrations/27-move-badge-settings-to-state-providers";
|
||||
import { MoveBiometricUnlockToStateProviders } from "./migrations/28-move-biometric-unlock-to-state-providers";
|
||||
import { UserNotificationSettingsKeyMigrator } from "./migrations/29-move-user-notification-settings-to-state-provider";
|
||||
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";
|
||||
@@ -33,7 +34,7 @@ import { MoveBrowserSettingsToGlobal } from "./migrations/9-move-browser-setting
|
||||
import { MinVersionMigrator } from "./migrations/min-version";
|
||||
|
||||
export const MIN_VERSION = 2;
|
||||
export const CURRENT_VERSION = 28;
|
||||
export const CURRENT_VERSION = 29;
|
||||
export type MinVersion = typeof MIN_VERSION;
|
||||
|
||||
export function createMigrationBuilder() {
|
||||
@@ -64,7 +65,8 @@ export function createMigrationBuilder() {
|
||||
.with(ClearClipboardDelayMigrator, 24, 25)
|
||||
.with(RevertLastSyncMigrator, 25, 26)
|
||||
.with(BadgeSettingsMigrator, 26, 27)
|
||||
.with(MoveBiometricUnlockToStateProviders, 27, CURRENT_VERSION);
|
||||
.with(MoveBiometricUnlockToStateProviders, 27, 28)
|
||||
.with(UserNotificationSettingsKeyMigrator, 28, CURRENT_VERSION);
|
||||
}
|
||||
|
||||
export async function currentVersion(
|
||||
|
||||
@@ -0,0 +1,102 @@
|
||||
import { MockProxy } from "jest-mock-extended";
|
||||
|
||||
import { StateDefinitionLike, MigrationHelper } from "../migration-helper";
|
||||
import { mockMigrationHelper } from "../migration-helper.spec";
|
||||
|
||||
import { UserNotificationSettingsKeyMigrator } from "./29-move-user-notification-settings-to-state-provider";
|
||||
|
||||
function exampleJSON() {
|
||||
return {
|
||||
global: {
|
||||
disableAddLoginNotification: false,
|
||||
disableChangedPasswordNotification: false,
|
||||
otherStuff: "otherStuff1",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function rollbackJSON() {
|
||||
return {
|
||||
global_userNotificationSettings_enableAddedLoginPrompt: true,
|
||||
global_userNotificationSettings_enableChangedPasswordPrompt: true,
|
||||
global: {
|
||||
otherStuff: "otherStuff1",
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
const userNotificationSettingsLocalStateDefinition: {
|
||||
stateDefinition: StateDefinitionLike;
|
||||
} = {
|
||||
stateDefinition: {
|
||||
name: "userNotificationSettings",
|
||||
},
|
||||
};
|
||||
|
||||
describe("ProviderKeysMigrator", () => {
|
||||
let helper: MockProxy<MigrationHelper>;
|
||||
let sut: UserNotificationSettingsKeyMigrator;
|
||||
|
||||
describe("migrate", () => {
|
||||
beforeEach(() => {
|
||||
helper = mockMigrationHelper(exampleJSON(), 28);
|
||||
sut = new UserNotificationSettingsKeyMigrator(28, 29);
|
||||
});
|
||||
|
||||
it("should remove disableAddLoginNotification and disableChangedPasswordNotification global setting", async () => {
|
||||
await sut.migrate(helper);
|
||||
expect(helper.set).toHaveBeenCalledTimes(2);
|
||||
expect(helper.set).toHaveBeenCalledWith("global", { otherStuff: "otherStuff1" });
|
||||
expect(helper.set).toHaveBeenCalledWith("global", { otherStuff: "otherStuff1" });
|
||||
});
|
||||
|
||||
it("should set global user notification setting values", async () => {
|
||||
await sut.migrate(helper);
|
||||
|
||||
expect(helper.setToGlobal).toHaveBeenCalledTimes(2);
|
||||
expect(helper.setToGlobal).toHaveBeenCalledWith(
|
||||
{ ...userNotificationSettingsLocalStateDefinition, key: "enableAddedLoginPrompt" },
|
||||
true,
|
||||
);
|
||||
expect(helper.setToGlobal).toHaveBeenCalledWith(
|
||||
{ ...userNotificationSettingsLocalStateDefinition, key: "enableChangedPasswordPrompt" },
|
||||
true,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("rollback", () => {
|
||||
beforeEach(() => {
|
||||
helper = mockMigrationHelper(rollbackJSON(), 29);
|
||||
sut = new UserNotificationSettingsKeyMigrator(28, 29);
|
||||
});
|
||||
|
||||
it("should null out new global values", async () => {
|
||||
await sut.rollback(helper);
|
||||
|
||||
expect(helper.setToGlobal).toHaveBeenCalledTimes(2);
|
||||
expect(helper.setToGlobal).toHaveBeenCalledWith(
|
||||
{ ...userNotificationSettingsLocalStateDefinition, key: "enableAddedLoginPrompt" },
|
||||
null,
|
||||
);
|
||||
expect(helper.setToGlobal).toHaveBeenCalledWith(
|
||||
{ ...userNotificationSettingsLocalStateDefinition, key: "enableChangedPasswordPrompt" },
|
||||
null,
|
||||
);
|
||||
});
|
||||
|
||||
it("should add explicit global values back", async () => {
|
||||
await sut.rollback(helper);
|
||||
|
||||
expect(helper.set).toHaveBeenCalledTimes(2);
|
||||
expect(helper.set).toHaveBeenCalledWith("global", {
|
||||
disableAddLoginNotification: false,
|
||||
otherStuff: "otherStuff1",
|
||||
});
|
||||
expect(helper.set).toHaveBeenCalledWith("global", {
|
||||
disableChangedPasswordNotification: false,
|
||||
otherStuff: "otherStuff1",
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,105 @@
|
||||
import { MigrationHelper } from "../migration-helper";
|
||||
import { Migrator } from "../migrator";
|
||||
|
||||
type ExpectedGlobalState = {
|
||||
disableAddLoginNotification?: boolean;
|
||||
disableChangedPasswordNotification?: boolean;
|
||||
};
|
||||
|
||||
export class UserNotificationSettingsKeyMigrator extends Migrator<28, 29> {
|
||||
async migrate(helper: MigrationHelper): Promise<void> {
|
||||
const globalState = await helper.get<ExpectedGlobalState>("global");
|
||||
|
||||
// disableAddLoginNotification -> enableAddedLoginPrompt
|
||||
if (globalState?.disableAddLoginNotification != null) {
|
||||
await helper.setToGlobal(
|
||||
{
|
||||
stateDefinition: {
|
||||
name: "userNotificationSettings",
|
||||
},
|
||||
key: "enableAddedLoginPrompt",
|
||||
},
|
||||
!globalState.disableAddLoginNotification,
|
||||
);
|
||||
|
||||
// delete `disableAddLoginNotification` from state global
|
||||
delete globalState.disableAddLoginNotification;
|
||||
|
||||
await helper.set<ExpectedGlobalState>("global", globalState);
|
||||
}
|
||||
|
||||
// disableChangedPasswordNotification -> enableChangedPasswordPrompt
|
||||
if (globalState?.disableChangedPasswordNotification != null) {
|
||||
await helper.setToGlobal(
|
||||
{
|
||||
stateDefinition: {
|
||||
name: "userNotificationSettings",
|
||||
},
|
||||
key: "enableChangedPasswordPrompt",
|
||||
},
|
||||
!globalState.disableChangedPasswordNotification,
|
||||
);
|
||||
|
||||
// delete `disableChangedPasswordNotification` from state global
|
||||
delete globalState.disableChangedPasswordNotification;
|
||||
|
||||
await helper.set<ExpectedGlobalState>("global", globalState);
|
||||
}
|
||||
}
|
||||
|
||||
async rollback(helper: MigrationHelper): Promise<void> {
|
||||
const globalState = (await helper.get<ExpectedGlobalState>("global")) || {};
|
||||
|
||||
const enableAddedLoginPrompt: boolean = await helper.getFromGlobal({
|
||||
stateDefinition: {
|
||||
name: "userNotificationSettings",
|
||||
},
|
||||
key: "enableAddedLoginPrompt",
|
||||
});
|
||||
|
||||
const enableChangedPasswordPrompt: boolean = await helper.getFromGlobal({
|
||||
stateDefinition: {
|
||||
name: "userNotificationSettings",
|
||||
},
|
||||
key: "enableChangedPasswordPrompt",
|
||||
});
|
||||
|
||||
// enableAddedLoginPrompt -> disableAddLoginNotification
|
||||
if (enableAddedLoginPrompt) {
|
||||
await helper.set<ExpectedGlobalState>("global", {
|
||||
...globalState,
|
||||
disableAddLoginNotification: !enableAddedLoginPrompt,
|
||||
});
|
||||
|
||||
// remove the global state provider framework key for `enableAddedLoginPrompt`
|
||||
await helper.setToGlobal(
|
||||
{
|
||||
stateDefinition: {
|
||||
name: "userNotificationSettings",
|
||||
},
|
||||
key: "enableAddedLoginPrompt",
|
||||
},
|
||||
null,
|
||||
);
|
||||
}
|
||||
|
||||
// enableChangedPasswordPrompt -> disableChangedPasswordNotification
|
||||
if (enableChangedPasswordPrompt) {
|
||||
await helper.set<ExpectedGlobalState>("global", {
|
||||
...globalState,
|
||||
disableChangedPasswordNotification: !enableChangedPasswordPrompt,
|
||||
});
|
||||
|
||||
// remove the global state provider framework key for `enableChangedPasswordPrompt`
|
||||
await helper.setToGlobal(
|
||||
{
|
||||
stateDefinition: {
|
||||
name: "userNotificationSettings",
|
||||
},
|
||||
key: "enableChangedPasswordPrompt",
|
||||
},
|
||||
null,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user