mirror of
https://github.com/bitwarden/browser.git
synced 2025-01-13 19:51:37 +01:00
[PM-11619] Replace client-side feature flag with server-side flag (#10709)
This commit is contained in:
parent
f0fe397307
commit
03b3345bf6
@ -2,7 +2,6 @@
|
|||||||
"devFlags": {},
|
"devFlags": {},
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": true,
|
"showPasswordless": true,
|
||||||
"enableCipherKeyEncryption": false,
|
|
||||||
"accountSwitching": false
|
"accountSwitching": false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
},
|
},
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": true,
|
"showPasswordless": true,
|
||||||
"enableCipherKeyEncryption": false,
|
|
||||||
"accountSwitching": true
|
"accountSwitching": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
{
|
{
|
||||||
"flags": {
|
"flags": {
|
||||||
"enableCipherKeyEncryption": false,
|
|
||||||
"accountSwitching": true
|
"accountSwitching": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"flags": {
|
"flags": {}
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"flags": {
|
"flags": {}
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
{
|
{
|
||||||
"devFlags": {},
|
"devFlags": {},
|
||||||
"flags": {
|
"flags": {}
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
{
|
{
|
||||||
"devFlags": {},
|
"devFlags": {},
|
||||||
"flags": {
|
"flags": {}
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
{
|
{
|
||||||
"flags": {
|
"flags": {}
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"allowedHosts": "auto"
|
"allowedHosts": "auto"
|
||||||
},
|
},
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": false,
|
"showPasswordless": false
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
"proxyNotifications": "https://notifications.bitwarden.com"
|
"proxyNotifications": "https://notifications.bitwarden.com"
|
||||||
},
|
},
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": true,
|
"showPasswordless": true
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": true,
|
"showPasswordless": true
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
},
|
},
|
||||||
"devFlags": {}
|
"devFlags": {}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@
|
|||||||
"buttonAction": "https://www.paypal.com/cgi-bin/webscr"
|
"buttonAction": "https://www.paypal.com/cgi-bin/webscr"
|
||||||
},
|
},
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": true,
|
"showPasswordless": true
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
}
|
}
|
||||||
],
|
],
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": true,
|
"showPasswordless": true
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@
|
|||||||
"port": 8081
|
"port": 8081
|
||||||
},
|
},
|
||||||
"flags": {
|
"flags": {
|
||||||
"showPasswordless": true,
|
"showPasswordless": true
|
||||||
"enableCipherKeyEncryption": false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ export enum FeatureFlag {
|
|||||||
AccountDeprovisioning = "pm-10308-account-deprovisioning",
|
AccountDeprovisioning = "pm-10308-account-deprovisioning",
|
||||||
NotificationBarAddLoginImprovements = "notification-bar-add-login-improvements",
|
NotificationBarAddLoginImprovements = "notification-bar-add-login-improvements",
|
||||||
AC2476_DeprecateStripeSourcesAPI = "AC-2476-deprecate-stripe-sources-api",
|
AC2476_DeprecateStripeSourcesAPI = "AC-2476-deprecate-stripe-sources-api",
|
||||||
|
CipherKeyEncryption = "cipher-key-encryption",
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AllowedFeatureFlagTypes = boolean | number | string;
|
export type AllowedFeatureFlagTypes = boolean | number | string;
|
||||||
@ -78,6 +79,7 @@ export const DefaultFeatureFlagValue = {
|
|||||||
[FeatureFlag.AccountDeprovisioning]: FALSE,
|
[FeatureFlag.AccountDeprovisioning]: FALSE,
|
||||||
[FeatureFlag.NotificationBarAddLoginImprovements]: FALSE,
|
[FeatureFlag.NotificationBarAddLoginImprovements]: FALSE,
|
||||||
[FeatureFlag.AC2476_DeprecateStripeSourcesAPI]: FALSE,
|
[FeatureFlag.AC2476_DeprecateStripeSourcesAPI]: FALSE,
|
||||||
|
[FeatureFlag.CipherKeyEncryption]: FALSE,
|
||||||
} satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>;
|
} satisfies Record<FeatureFlag, AllowedFeatureFlagTypes>;
|
||||||
|
|
||||||
export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;
|
export type DefaultFeatureFlagValueType = typeof DefaultFeatureFlagValue;
|
||||||
|
@ -2,7 +2,6 @@
|
|||||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
export type SharedFlags = {
|
export type SharedFlags = {
|
||||||
showPasswordless?: boolean;
|
showPasswordless?: boolean;
|
||||||
enableCipherKeyEncryption?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// required to avoid linting errors when there are no flags
|
// required to avoid linting errors when there are no flags
|
||||||
|
@ -166,7 +166,7 @@ describe("Cipher Service", () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
configService.checkServerMeetsVersionRequirement$.mockReturnValue(of(false));
|
configService.checkServerMeetsVersionRequirement$.mockReturnValue(of(false));
|
||||||
setEncryptionKeyFlag(false);
|
configService.getFeatureFlag.mockResolvedValue(false);
|
||||||
|
|
||||||
const spy = jest.spyOn(cipherFileUploadService, "upload");
|
const spy = jest.spyOn(cipherFileUploadService, "upload");
|
||||||
|
|
||||||
@ -298,16 +298,16 @@ describe("Cipher Service", () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
describe("cipher.key", () => {
|
describe("cipher.key", () => {
|
||||||
it("is null when enableCipherKeyEncryption flag is false", async () => {
|
it("is null when feature flag is false", async () => {
|
||||||
setEncryptionKeyFlag(false);
|
configService.getFeatureFlag.mockResolvedValue(false);
|
||||||
|
|
||||||
const cipher = await cipherService.encrypt(cipherView, userId);
|
const cipher = await cipherService.encrypt(cipherView, userId);
|
||||||
|
|
||||||
expect(cipher.key).toBeNull();
|
expect(cipher.key).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("is defined when enableCipherKeyEncryption flag is true", async () => {
|
it("is defined when feature flag flag is true", async () => {
|
||||||
setEncryptionKeyFlag(true);
|
configService.getFeatureFlag.mockResolvedValue(true);
|
||||||
|
|
||||||
const cipher = await cipherService.encrypt(cipherView, userId);
|
const cipher = await cipherService.encrypt(cipherView, userId);
|
||||||
|
|
||||||
@ -320,16 +320,16 @@ describe("Cipher Service", () => {
|
|||||||
jest.spyOn<any, string>(cipherService, "encryptCipherWithCipherKey");
|
jest.spyOn<any, string>(cipherService, "encryptCipherWithCipherKey");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("is not called when enableCipherKeyEncryption is false", async () => {
|
it("is not called when feature flag is false", async () => {
|
||||||
setEncryptionKeyFlag(false);
|
configService.getFeatureFlag.mockResolvedValue(false);
|
||||||
|
|
||||||
await cipherService.encrypt(cipherView, userId);
|
await cipherService.encrypt(cipherView, userId);
|
||||||
|
|
||||||
expect(cipherService["encryptCipherWithCipherKey"]).not.toHaveBeenCalled();
|
expect(cipherService["encryptCipherWithCipherKey"]).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
it("is called when enableCipherKeyEncryption is true", async () => {
|
it("is called when feature flag is true", async () => {
|
||||||
setEncryptionKeyFlag(true);
|
configService.getFeatureFlag.mockResolvedValue(true);
|
||||||
|
|
||||||
await cipherService.encrypt(cipherView, userId);
|
await cipherService.encrypt(cipherView, userId);
|
||||||
|
|
||||||
@ -345,7 +345,7 @@ describe("Cipher Service", () => {
|
|||||||
let encryptedKey: EncString;
|
let encryptedKey: EncString;
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
setEncryptionKeyFlag(true);
|
configService.getFeatureFlag.mockResolvedValue(true);
|
||||||
configService.checkServerMeetsVersionRequirement$.mockReturnValue(of(true));
|
configService.checkServerMeetsVersionRequirement$.mockReturnValue(of(true));
|
||||||
|
|
||||||
searchService.indexedEntityId$ = of(null);
|
searchService.indexedEntityId$ = of(null);
|
||||||
@ -398,9 +398,3 @@ describe("Cipher Service", () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function setEncryptionKeyFlag(value: boolean) {
|
|
||||||
process.env.FLAGS = JSON.stringify({
|
|
||||||
enableCipherKeyEncryption: value,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
@ -17,7 +17,6 @@ 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 { flagEnabled } from "../../platform/misc/flags";
|
|
||||||
import { sequentialize } from "../../platform/misc/sequentialize";
|
import { sequentialize } from "../../platform/misc/sequentialize";
|
||||||
import { Utils } from "../../platform/misc/utils";
|
import { Utils } from "../../platform/misc/utils";
|
||||||
import Domain from "../../platform/models/domain/domain-base";
|
import Domain from "../../platform/models/domain/domain-base";
|
||||||
@ -1662,11 +1661,10 @@ export class CipherService implements CipherServiceAbstraction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async getCipherKeyEncryptionEnabled(): Promise<boolean> {
|
private async getCipherKeyEncryptionEnabled(): Promise<boolean> {
|
||||||
return (
|
const featureEnabled = await this.configService.getFeatureFlag(FeatureFlag.CipherKeyEncryption);
|
||||||
flagEnabled("enableCipherKeyEncryption") &&
|
const meetsServerVersion = await firstValueFrom(
|
||||||
(await firstValueFrom(
|
|
||||||
this.configService.checkServerMeetsVersionRequirement$(CIPHER_KEY_ENC_MIN_SERVER_VER),
|
this.configService.checkServerMeetsVersionRequirement$(CIPHER_KEY_ENC_MIN_SERVER_VER),
|
||||||
))
|
|
||||||
);
|
);
|
||||||
|
return featureEnabled && meetsServerVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user