From 03b3345bf60900adc63bc1490ec782a091a3ab8e Mon Sep 17 00:00:00 2001 From: Todd Martin <106564991+trmartin4@users.noreply.github.com> Date: Fri, 6 Sep 2024 09:25:15 -0400 Subject: [PATCH] [PM-11619] Replace client-side feature flag with server-side flag (#10709) --- apps/browser/config/base.json | 1 - apps/browser/config/development.json | 1 - apps/browser/config/production.json | 1 - apps/cli/config/development.json | 4 +-- apps/cli/config/production.json | 4 +-- apps/desktop/config/base.json | 4 +-- apps/desktop/config/development.json | 4 +-- apps/desktop/config/production.json | 4 +-- apps/web/config/base.json | 3 +-- apps/web/config/cloud.json | 3 +-- apps/web/config/development.json | 3 +-- apps/web/config/euprd.json | 3 +-- apps/web/config/qa.json | 3 +-- apps/web/config/selfhosted.json | 3 +-- libs/common/src/enums/feature-flag.enum.ts | 2 ++ libs/common/src/platform/misc/flags.ts | 1 - .../src/vault/services/cipher.service.spec.ts | 26 +++++++------------ .../src/vault/services/cipher.service.ts | 10 +++---- 18 files changed, 27 insertions(+), 53 deletions(-) diff --git a/apps/browser/config/base.json b/apps/browser/config/base.json index 6c428c43d26..5113cd7d1bf 100644 --- a/apps/browser/config/base.json +++ b/apps/browser/config/base.json @@ -2,7 +2,6 @@ "devFlags": {}, "flags": { "showPasswordless": true, - "enableCipherKeyEncryption": false, "accountSwitching": false } } diff --git a/apps/browser/config/development.json b/apps/browser/config/development.json index e0925ebecc9..cc28e15f38b 100644 --- a/apps/browser/config/development.json +++ b/apps/browser/config/development.json @@ -7,7 +7,6 @@ }, "flags": { "showPasswordless": true, - "enableCipherKeyEncryption": false, "accountSwitching": true } } diff --git a/apps/browser/config/production.json b/apps/browser/config/production.json index 027003f6c75..a43eee1d5c9 100644 --- a/apps/browser/config/production.json +++ b/apps/browser/config/production.json @@ -1,6 +1,5 @@ { "flags": { - "enableCipherKeyEncryption": false, "accountSwitching": true } } diff --git a/apps/cli/config/development.json b/apps/cli/config/development.json index f57c3d9bc38..b04d1531a2f 100644 --- a/apps/cli/config/development.json +++ b/apps/cli/config/development.json @@ -1,5 +1,3 @@ { - "flags": { - "enableCipherKeyEncryption": false - } + "flags": {} } diff --git a/apps/cli/config/production.json b/apps/cli/config/production.json index f57c3d9bc38..b04d1531a2f 100644 --- a/apps/cli/config/production.json +++ b/apps/cli/config/production.json @@ -1,5 +1,3 @@ { - "flags": { - "enableCipherKeyEncryption": false - } + "flags": {} } diff --git a/apps/desktop/config/base.json b/apps/desktop/config/base.json index 7a8659feffe..3c93018e65f 100644 --- a/apps/desktop/config/base.json +++ b/apps/desktop/config/base.json @@ -1,6 +1,4 @@ { "devFlags": {}, - "flags": { - "enableCipherKeyEncryption": false - } + "flags": {} } diff --git a/apps/desktop/config/development.json b/apps/desktop/config/development.json index 7a8659feffe..3c93018e65f 100644 --- a/apps/desktop/config/development.json +++ b/apps/desktop/config/development.json @@ -1,6 +1,4 @@ { "devFlags": {}, - "flags": { - "enableCipherKeyEncryption": false - } + "flags": {} } diff --git a/apps/desktop/config/production.json b/apps/desktop/config/production.json index f57c3d9bc38..b04d1531a2f 100644 --- a/apps/desktop/config/production.json +++ b/apps/desktop/config/production.json @@ -1,5 +1,3 @@ { - "flags": { - "enableCipherKeyEncryption": false - } + "flags": {} } diff --git a/apps/web/config/base.json b/apps/web/config/base.json index 5dc03a4633d..8eb8a311335 100644 --- a/apps/web/config/base.json +++ b/apps/web/config/base.json @@ -11,7 +11,6 @@ "allowedHosts": "auto" }, "flags": { - "showPasswordless": false, - "enableCipherKeyEncryption": false + "showPasswordless": false } } diff --git a/apps/web/config/cloud.json b/apps/web/config/cloud.json index 3faa2926929..8817142c9ed 100644 --- a/apps/web/config/cloud.json +++ b/apps/web/config/cloud.json @@ -17,7 +17,6 @@ "proxyNotifications": "https://notifications.bitwarden.com" }, "flags": { - "showPasswordless": true, - "enableCipherKeyEncryption": false + "showPasswordless": true } } diff --git a/apps/web/config/development.json b/apps/web/config/development.json index 44391a7450d..58dec82a154 100644 --- a/apps/web/config/development.json +++ b/apps/web/config/development.json @@ -20,8 +20,7 @@ } ], "flags": { - "showPasswordless": true, - "enableCipherKeyEncryption": false + "showPasswordless": true }, "devFlags": {} } diff --git a/apps/web/config/euprd.json b/apps/web/config/euprd.json index 72f0c1857d9..99d98ca09dd 100644 --- a/apps/web/config/euprd.json +++ b/apps/web/config/euprd.json @@ -11,7 +11,6 @@ "buttonAction": "https://www.paypal.com/cgi-bin/webscr" }, "flags": { - "showPasswordless": true, - "enableCipherKeyEncryption": false + "showPasswordless": true } } diff --git a/apps/web/config/qa.json b/apps/web/config/qa.json index ac36b107846..07e341e6f9f 100644 --- a/apps/web/config/qa.json +++ b/apps/web/config/qa.json @@ -27,7 +27,6 @@ } ], "flags": { - "showPasswordless": true, - "enableCipherKeyEncryption": false + "showPasswordless": true } } diff --git a/apps/web/config/selfhosted.json b/apps/web/config/selfhosted.json index 7e916a11169..9d8e1cf2685 100644 --- a/apps/web/config/selfhosted.json +++ b/apps/web/config/selfhosted.json @@ -7,7 +7,6 @@ "port": 8081 }, "flags": { - "showPasswordless": true, - "enableCipherKeyEncryption": false + "showPasswordless": true } } diff --git a/libs/common/src/enums/feature-flag.enum.ts b/libs/common/src/enums/feature-flag.enum.ts index 8e88cda6178..9ec88f019ee 100644 --- a/libs/common/src/enums/feature-flag.enum.ts +++ b/libs/common/src/enums/feature-flag.enum.ts @@ -34,6 +34,7 @@ export enum FeatureFlag { AccountDeprovisioning = "pm-10308-account-deprovisioning", NotificationBarAddLoginImprovements = "notification-bar-add-login-improvements", AC2476_DeprecateStripeSourcesAPI = "AC-2476-deprecate-stripe-sources-api", + CipherKeyEncryption = "cipher-key-encryption", } export type AllowedFeatureFlagTypes = boolean | number | string; @@ -78,6 +79,7 @@ export const DefaultFeatureFlagValue = { [FeatureFlag.AccountDeprovisioning]: FALSE, [FeatureFlag.NotificationBarAddLoginImprovements]: FALSE, [FeatureFlag.AC2476_DeprecateStripeSourcesAPI]: FALSE, + [FeatureFlag.CipherKeyEncryption]: FALSE, } satisfies Record; export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue; diff --git a/libs/common/src/platform/misc/flags.ts b/libs/common/src/platform/misc/flags.ts index 747d82b9a9f..3a305676812 100644 --- a/libs/common/src/platform/misc/flags.ts +++ b/libs/common/src/platform/misc/flags.ts @@ -2,7 +2,6 @@ // eslint-disable-next-line @typescript-eslint/ban-types export type SharedFlags = { showPasswordless?: boolean; - enableCipherKeyEncryption?: boolean; }; // required to avoid linting errors when there are no flags diff --git a/libs/common/src/vault/services/cipher.service.spec.ts b/libs/common/src/vault/services/cipher.service.spec.ts index b6b35f1886a..b2712dee559 100644 --- a/libs/common/src/vault/services/cipher.service.spec.ts +++ b/libs/common/src/vault/services/cipher.service.spec.ts @@ -166,7 +166,7 @@ describe("Cipher Service", () => { ); configService.checkServerMeetsVersionRequirement$.mockReturnValue(of(false)); - setEncryptionKeyFlag(false); + configService.getFeatureFlag.mockResolvedValue(false); const spy = jest.spyOn(cipherFileUploadService, "upload"); @@ -298,16 +298,16 @@ describe("Cipher Service", () => { }); describe("cipher.key", () => { - it("is null when enableCipherKeyEncryption flag is false", async () => { - setEncryptionKeyFlag(false); + it("is null when feature flag is false", async () => { + configService.getFeatureFlag.mockResolvedValue(false); const cipher = await cipherService.encrypt(cipherView, userId); expect(cipher.key).toBeNull(); }); - it("is defined when enableCipherKeyEncryption flag is true", async () => { - setEncryptionKeyFlag(true); + it("is defined when feature flag flag is true", async () => { + configService.getFeatureFlag.mockResolvedValue(true); const cipher = await cipherService.encrypt(cipherView, userId); @@ -320,16 +320,16 @@ describe("Cipher Service", () => { jest.spyOn(cipherService, "encryptCipherWithCipherKey"); }); - it("is not called when enableCipherKeyEncryption is false", async () => { - setEncryptionKeyFlag(false); + it("is not called when feature flag is false", async () => { + configService.getFeatureFlag.mockResolvedValue(false); await cipherService.encrypt(cipherView, userId); expect(cipherService["encryptCipherWithCipherKey"]).not.toHaveBeenCalled(); }); - it("is called when enableCipherKeyEncryption is true", async () => { - setEncryptionKeyFlag(true); + it("is called when feature flag is true", async () => { + configService.getFeatureFlag.mockResolvedValue(true); await cipherService.encrypt(cipherView, userId); @@ -345,7 +345,7 @@ describe("Cipher Service", () => { let encryptedKey: EncString; beforeEach(() => { - setEncryptionKeyFlag(true); + configService.getFeatureFlag.mockResolvedValue(true); configService.checkServerMeetsVersionRequirement$.mockReturnValue(of(true)); searchService.indexedEntityId$ = of(null); @@ -398,9 +398,3 @@ describe("Cipher Service", () => { }); }); }); - -function setEncryptionKeyFlag(value: boolean) { - process.env.FLAGS = JSON.stringify({ - enableCipherKeyEncryption: value, - }); -} diff --git a/libs/common/src/vault/services/cipher.service.ts b/libs/common/src/vault/services/cipher.service.ts index cb72d413c8f..70b7c77fc15 100644 --- a/libs/common/src/vault/services/cipher.service.ts +++ b/libs/common/src/vault/services/cipher.service.ts @@ -17,7 +17,6 @@ import { CryptoService } from "../../platform/abstractions/crypto.service"; import { EncryptService } from "../../platform/abstractions/encrypt.service"; import { I18nService } from "../../platform/abstractions/i18n.service"; import { StateService } from "../../platform/abstractions/state.service"; -import { flagEnabled } from "../../platform/misc/flags"; import { sequentialize } from "../../platform/misc/sequentialize"; import { Utils } from "../../platform/misc/utils"; import Domain from "../../platform/models/domain/domain-base"; @@ -1662,11 +1661,10 @@ export class CipherService implements CipherServiceAbstraction { } private async getCipherKeyEncryptionEnabled(): Promise { - return ( - flagEnabled("enableCipherKeyEncryption") && - (await firstValueFrom( - this.configService.checkServerMeetsVersionRequirement$(CIPHER_KEY_ENC_MIN_SERVER_VER), - )) + const featureEnabled = await this.configService.getFeatureFlag(FeatureFlag.CipherKeyEncryption); + const meetsServerVersion = await firstValueFrom( + this.configService.checkServerMeetsVersionRequirement$(CIPHER_KEY_ENC_MIN_SERVER_VER), ); + return featureEnabled && meetsServerVersion; } }