From fdd4d4b9fe8c083878a4c62b58cd4af49392ec97 Mon Sep 17 00:00:00 2001 From: Jason Ng Date: Fri, 6 Jun 2025 09:53:08 -0400 Subject: [PATCH] [PM-22270] Only Show Generator Nudge For New Accounts (#15059) * create new account nudge service to replace repeat nudge services checking for 30 day limit --- .../download-bitwarden-nudge.service.ts | 42 ------------------- .../services/custom-nudges-services/index.ts | 3 +- ...ervice.ts => new-account-nudge.service.ts} | 8 ++-- .../src/vault/services/nudges.service.spec.ts | 8 ++-- .../src/vault/services/nudges.service.ts | 9 ++-- 5 files changed, 14 insertions(+), 56 deletions(-) delete mode 100644 libs/angular/src/vault/services/custom-nudges-services/download-bitwarden-nudge.service.ts rename libs/angular/src/vault/services/custom-nudges-services/{autofill-nudge.service.ts => new-account-nudge.service.ts} (84%) diff --git a/libs/angular/src/vault/services/custom-nudges-services/download-bitwarden-nudge.service.ts b/libs/angular/src/vault/services/custom-nudges-services/download-bitwarden-nudge.service.ts deleted file mode 100644 index 706b23437a1..00000000000 --- a/libs/angular/src/vault/services/custom-nudges-services/download-bitwarden-nudge.service.ts +++ /dev/null @@ -1,42 +0,0 @@ -import { Injectable, inject } from "@angular/core"; -import { Observable, combineLatest, from, of } from "rxjs"; -import { catchError, map } from "rxjs/operators"; - -import { VaultProfileService } from "@bitwarden/angular/vault/services/vault-profile.service"; -import { LogService } from "@bitwarden/common/platform/abstractions/log.service"; -import { UserId } from "@bitwarden/common/types/guid"; - -import { DefaultSingleNudgeService } from "../default-single-nudge.service"; -import { NudgeStatus, NudgeType } from "../nudges.service"; - -const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000; - -@Injectable({ providedIn: "root" }) -export class DownloadBitwardenNudgeService extends DefaultSingleNudgeService { - private vaultProfileService = inject(VaultProfileService); - private logService = inject(LogService); - - nudgeStatus$(nudgeType: NudgeType, userId: UserId): Observable { - const profileDate$ = from(this.vaultProfileService.getProfileCreationDate(userId)).pipe( - catchError(() => { - this.logService.error("Failed to load profile date:"); - // Default to today to ensure the nudge is shown - return of(new Date()); - }), - ); - - return combineLatest([ - profileDate$, - this.getNudgeStatus$(nudgeType, userId), - of(Date.now() - THIRTY_DAYS_MS), - ]).pipe( - map(([profileCreationDate, status, profileCutoff]) => { - const profileOlderThanCutoff = profileCreationDate.getTime() < profileCutoff; - return { - hasBadgeDismissed: status.hasBadgeDismissed || profileOlderThanCutoff, - hasSpotlightDismissed: status.hasSpotlightDismissed || profileOlderThanCutoff, - }; - }), - ); - } -} diff --git a/libs/angular/src/vault/services/custom-nudges-services/index.ts b/libs/angular/src/vault/services/custom-nudges-services/index.ts index 10b6b45aa1d..f60592b9c71 100644 --- a/libs/angular/src/vault/services/custom-nudges-services/index.ts +++ b/libs/angular/src/vault/services/custom-nudges-services/index.ts @@ -1,7 +1,6 @@ -export * from "./autofill-nudge.service"; export * from "./account-security-nudge.service"; export * from "./has-items-nudge.service"; -export * from "./download-bitwarden-nudge.service"; export * from "./empty-vault-nudge.service"; export * from "./vault-settings-import-nudge.service"; export * from "./new-item-nudge.service"; +export * from "./new-account-nudge.service"; diff --git a/libs/angular/src/vault/services/custom-nudges-services/autofill-nudge.service.ts b/libs/angular/src/vault/services/custom-nudges-services/new-account-nudge.service.ts similarity index 84% rename from libs/angular/src/vault/services/custom-nudges-services/autofill-nudge.service.ts rename to libs/angular/src/vault/services/custom-nudges-services/new-account-nudge.service.ts index 0a04fb2be47..39af9a2e4aa 100644 --- a/libs/angular/src/vault/services/custom-nudges-services/autofill-nudge.service.ts +++ b/libs/angular/src/vault/services/custom-nudges-services/new-account-nudge.service.ts @@ -12,16 +12,16 @@ import { NudgeStatus, NudgeType } from "../nudges.service"; const THIRTY_DAYS_MS = 30 * 24 * 60 * 60 * 1000; /** - * Custom Nudge Service to use for the Autofill Nudge in the Vault + * Custom Nudge Service to check if account is older than 30 days */ @Injectable({ providedIn: "root", }) -export class AutofillNudgeService extends DefaultSingleNudgeService { +export class NewAccountNudgeService extends DefaultSingleNudgeService { vaultProfileService = inject(VaultProfileService); logService = inject(LogService); - nudgeStatus$(_: NudgeType, userId: UserId): Observable { + nudgeStatus$(nudgeType: NudgeType, userId: UserId): Observable { const profileDate$ = from(this.vaultProfileService.getProfileCreationDate(userId)).pipe( catchError(() => { this.logService.error("Error getting profile creation date"); @@ -32,7 +32,7 @@ export class AutofillNudgeService extends DefaultSingleNudgeService { return combineLatest([ profileDate$, - this.getNudgeStatus$(NudgeType.AutofillNudge, userId), + this.getNudgeStatus$(nudgeType, userId), of(Date.now() - THIRTY_DAYS_MS), ]).pipe( map(([profileCreationDate, status, profileCutoff]) => { diff --git a/libs/angular/src/vault/services/nudges.service.spec.ts b/libs/angular/src/vault/services/nudges.service.spec.ts index db1091c0956..f18d846232c 100644 --- a/libs/angular/src/vault/services/nudges.service.spec.ts +++ b/libs/angular/src/vault/services/nudges.service.spec.ts @@ -19,7 +19,7 @@ import { FakeStateProvider, mockAccountServiceWith } from "../../../../../libs/c import { HasItemsNudgeService, EmptyVaultNudgeService, - DownloadBitwardenNudgeService, + NewAccountNudgeService, VaultSettingsImportNudgeService, } from "./custom-nudges-services"; import { DefaultSingleNudgeService } from "./default-single-nudge.service"; @@ -34,7 +34,7 @@ describe("Vault Nudges Service", () => { getFeatureFlag: jest.fn().mockReturnValue(true), }; - const nudgeServices = [EmptyVaultNudgeService, DownloadBitwardenNudgeService]; + const nudgeServices = [EmptyVaultNudgeService, NewAccountNudgeService]; beforeEach(async () => { fakeStateProvider = new FakeStateProvider(mockAccountServiceWith("user-id" as UserId)); @@ -58,8 +58,8 @@ describe("Vault Nudges Service", () => { useValue: mock(), }, { - provide: DownloadBitwardenNudgeService, - useValue: mock(), + provide: NewAccountNudgeService, + useValue: mock(), }, { provide: EmptyVaultNudgeService, diff --git a/libs/angular/src/vault/services/nudges.service.ts b/libs/angular/src/vault/services/nudges.service.ts index 25f0e30de7a..6e8c996c066 100644 --- a/libs/angular/src/vault/services/nudges.service.ts +++ b/libs/angular/src/vault/services/nudges.service.ts @@ -8,10 +8,9 @@ import { UserId } from "@bitwarden/common/types/guid"; import { UnionOfValues } from "@bitwarden/common/vault/types/union-of-values"; import { + NewAccountNudgeService, HasItemsNudgeService, EmptyVaultNudgeService, - AutofillNudgeService, - DownloadBitwardenNudgeService, NewItemNudgeService, AccountSecurityNudgeService, VaultSettingsImportNudgeService, @@ -56,6 +55,7 @@ export const NUDGE_DISMISSED_DISK_KEY = new UserKeyDefinition< }) export class NudgesService { private newItemNudgeService = inject(NewItemNudgeService); + private newAcctNudgeService = inject(NewAccountNudgeService); /** * Custom nudge services to use for specific nudge types @@ -67,8 +67,9 @@ export class NudgesService { [NudgeType.EmptyVaultNudge]: inject(EmptyVaultNudgeService), [NudgeType.VaultSettingsImportNudge]: inject(VaultSettingsImportNudgeService), [NudgeType.AccountSecurity]: inject(AccountSecurityNudgeService), - [NudgeType.AutofillNudge]: inject(AutofillNudgeService), - [NudgeType.DownloadBitwarden]: inject(DownloadBitwardenNudgeService), + [NudgeType.AutofillNudge]: this.newAcctNudgeService, + [NudgeType.DownloadBitwarden]: this.newAcctNudgeService, + [NudgeType.GeneratorNudgeStatus]: this.newAcctNudgeService, [NudgeType.NewLoginItemStatus]: this.newItemNudgeService, [NudgeType.NewCardItemStatus]: this.newItemNudgeService, [NudgeType.NewIdentityItemStatus]: this.newItemNudgeService,