1
0
mirror of https://github.com/bitwarden/browser synced 2026-01-28 15:23:53 +00:00

Merge branch 'main' into billing/pm-30908/correct-premium-subscription-status-handling

This commit is contained in:
cyprain-okeke
2026-01-26 19:55:42 +01:00
committed by GitHub
6 changed files with 16 additions and 91 deletions

View File

@@ -81,7 +81,7 @@
"lowdb": "1.0.0",
"lunr": "2.3.9",
"multer": "2.0.2",
"node-fetch": "2.6.12",
"node-fetch": "2.7.0",
"node-forge": "1.3.2",
"open": "11.0.0",
"papaparse": "5.5.3",

View File

@@ -65,7 +65,6 @@ export enum FeatureFlag {
PM22134SdkCipherListView = "pm-22134-sdk-cipher-list-view",
PM22136_SdkCipherEncryption = "pm-22136-sdk-cipher-encryption",
CipherKeyEncryption = "cipher-key-encryption",
RiskInsightsForPremium = "pm-23904-risk-insights-for-premium",
VaultLoadingSkeletons = "pm-25081-vault-skeleton-loaders",
BrowserPremiumSpotlight = "pm-23384-browser-premium-spotlight",
MigrateMyVaultToMyItems = "pm-20558-migrate-myvault-to-myitems",
@@ -129,7 +128,6 @@ export const DefaultFeatureFlagValue = {
[FeatureFlag.PM19941MigrateCipherDomainToSdk]: FALSE,
[FeatureFlag.PM22134SdkCipherListView]: FALSE,
[FeatureFlag.PM22136_SdkCipherEncryption]: FALSE,
[FeatureFlag.RiskInsightsForPremium]: FALSE,
[FeatureFlag.VaultLoadingSkeletons]: FALSE,
[FeatureFlag.BrowserPremiumSpotlight]: FALSE,
[FeatureFlag.MigrateMyVaultToMyItems]: FALSE,

View File

@@ -8,7 +8,6 @@ import { CollectionService } from "@bitwarden/admin-console/common";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AccountService, Account } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -42,11 +41,9 @@ describe("CipherViewComponent", () => {
let mockLogService: LogService;
let mockCipherRiskService: CipherRiskService;
let mockBillingAccountProfileStateService: BillingAccountProfileStateService;
let mockConfigService: ConfigService;
// Mock data
let mockCipherView: CipherView;
let featureFlagEnabled$: BehaviorSubject<boolean>;
let hasPremiumFromAnySource$: BehaviorSubject<boolean>;
let activeAccount$: BehaviorSubject<Account>;
@@ -57,7 +54,6 @@ describe("CipherViewComponent", () => {
email: "test@example.com",
} as Account);
featureFlagEnabled$ = new BehaviorSubject(false);
hasPremiumFromAnySource$ = new BehaviorSubject(true);
// Create service mocks
@@ -83,9 +79,6 @@ describe("CipherViewComponent", () => {
.fn()
.mockReturnValue(hasPremiumFromAnySource$);
mockConfigService = mock<ConfigService>();
mockConfigService.getFeatureFlag$ = jest.fn().mockReturnValue(featureFlagEnabled$);
// Setup mock cipher view
mockCipherView = new CipherView();
mockCipherView.id = "cipher-id";
@@ -110,7 +103,6 @@ describe("CipherViewComponent", () => {
provide: BillingAccountProfileStateService,
useValue: mockBillingAccountProfileStateService,
},
{ provide: ConfigService, useValue: mockConfigService },
],
schemas: [NO_ERRORS_SCHEMA],
})
@@ -145,7 +137,6 @@ describe("CipherViewComponent", () => {
beforeEach(() => {
// Reset observables to default values for this test suite
featureFlagEnabled$.next(true);
hasPremiumFromAnySource$.next(true);
// Setup default mock for computeCipherRiskForUser (individual tests can override)
@@ -162,18 +153,6 @@ describe("CipherViewComponent", () => {
component = fixture.componentInstance;
});
it("returns false when feature flag is disabled", fakeAsync(() => {
featureFlagEnabled$.next(false);
const cipher = createLoginCipherView();
fixture.componentRef.setInput("cipher", cipher);
fixture.detectChanges();
tick();
expect(mockCipherRiskService.computeCipherRiskForUser).not.toHaveBeenCalled();
expect(component.passwordIsAtRisk()).toBe(false);
}));
it("returns false when cipher has no login password", fakeAsync(() => {
const cipher = createLoginCipherView();
cipher.login = {} as any; // No password

View File

@@ -13,8 +13,6 @@ import { AccountService } from "@bitwarden/common/auth/abstractions/account.serv
import { getUserId } from "@bitwarden/common/auth/services/account.service";
import { isCardExpired } from "@bitwarden/common/autofill/utils";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions";
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { getByIds } from "@bitwarden/common/platform/misc";
@@ -113,7 +111,6 @@ export class CipherViewComponent {
private logService: LogService,
private cipherRiskService: CipherRiskService,
private billingAccountService: BillingAccountProfileStateService,
private configService: ConfigService,
) {}
readonly resolvedCollections = toSignal<CollectionView[] | undefined>(
@@ -248,19 +245,9 @@ export class CipherViewComponent {
* The password is only evaluated when the user is premium and has edit access to the cipher.
*/
readonly passwordIsAtRisk = toSignal(
combineLatest([
this.activeUserId$,
this.cipher$,
this.configService.getFeatureFlag$(FeatureFlag.RiskInsightsForPremium),
]).pipe(
switchMap(([userId, cipher, featureEnabled]) => {
if (
!featureEnabled ||
!cipher.hasLoginPassword ||
!cipher.edit ||
cipher.organizationId ||
cipher.isDeleted
) {
combineLatest([this.activeUserId$, this.cipher$]).pipe(
switchMap(([userId, cipher]) => {
if (!cipher.hasLoginPassword || !cipher.edit || cipher.organizationId || cipher.isDeleted) {
return of(false);
}
return this.switchPremium$(

59
package-lock.json generated
View File

@@ -52,7 +52,7 @@
"lunr": "2.3.9",
"multer": "2.0.2",
"ngx-toastr": "19.1.0",
"node-fetch": "2.6.12",
"node-fetch": "2.7.0",
"node-forge": "1.3.2",
"oidc-client-ts": "2.4.1",
"open": "11.0.0",
@@ -110,7 +110,7 @@
"@types/lowdb": "1.0.15",
"@types/lunr": "2.3.7",
"@types/node": "22.19.3",
"@types/node-fetch": "2.6.4",
"@types/node-fetch": "2.6.13",
"@types/node-forge": "1.3.14",
"@types/papaparse": "5.5.0",
"@types/proper-lockfile": "4.1.4",
@@ -217,7 +217,7 @@
"lowdb": "1.0.0",
"lunr": "2.3.9",
"multer": "2.0.2",
"node-fetch": "2.6.12",
"node-fetch": "2.7.0",
"node-forge": "1.3.2",
"open": "11.0.0",
"papaparse": "5.5.3",
@@ -15842,53 +15842,14 @@
}
},
"node_modules/@types/node-fetch": {
"version": "2.6.4",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.4.tgz",
"integrity": "sha512-1ZX9fcN4Rvkvgv4E6PAY5WXUFWFcRWxZa3EW83UjycOB9ljJCedb2CupIP4RZMEwF/M3eTcCihbBRgwtGbg5Rg==",
"version": "2.6.13",
"resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz",
"integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/node": "*",
"form-data": "^3.0.0"
}
},
"node_modules/@types/node-fetch/node_modules/form-data": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.3.tgz",
"integrity": "sha512-q5YBMeWy6E2Un0nMGWMgI65MAKtaylxfNJGJxpGh45YDciZB4epbWpaAfImil6CPAPTYB4sh0URQNDRIZG5F2w==",
"dev": true,
"license": "MIT",
"dependencies": {
"asynckit": "^0.4.0",
"combined-stream": "^1.0.8",
"es-set-tostringtag": "^2.1.0",
"mime-types": "^2.1.35"
},
"engines": {
"node": ">= 6"
}
},
"node_modules/@types/node-fetch/node_modules/mime-db": {
"version": "1.52.0",
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
"integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 0.6"
}
},
"node_modules/@types/node-fetch/node_modules/mime-types": {
"version": "2.1.35",
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
"integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
"dev": true,
"license": "MIT",
"dependencies": {
"mime-db": "1.52.0"
},
"engines": {
"node": ">= 0.6"
"form-data": "^4.0.4"
}
},
"node_modules/@types/node-forge": {
@@ -32816,9 +32777,9 @@
}
},
"node_modules/node-fetch": {
"version": "2.6.12",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.12.tgz",
"integrity": "sha512-C/fGU2E8ToujUivIO0H+tpQ6HWo4eEmchoPIoXtxCrVghxdKq+QOHqEZW7tuP3KlV3bC8FRMO5nMCC7Zm1VP6g==",
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
"integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
"license": "MIT",
"dependencies": {
"whatwg-url": "^5.0.0"

View File

@@ -77,7 +77,7 @@
"@types/lowdb": "1.0.15",
"@types/lunr": "2.3.7",
"@types/node": "22.19.3",
"@types/node-fetch": "2.6.4",
"@types/node-fetch": "2.6.13",
"@types/node-forge": "1.3.14",
"@types/papaparse": "5.5.0",
"@types/proper-lockfile": "4.1.4",
@@ -191,7 +191,7 @@
"lunr": "2.3.9",
"multer": "2.0.2",
"ngx-toastr": "19.1.0",
"node-fetch": "2.6.12",
"node-fetch": "2.7.0",
"node-forge": "1.3.2",
"oidc-client-ts": "2.4.1",
"open": "11.0.0",