- {{ "save" | i18n }}
+ {{ "upgrade" | i18n }}
{{ "cancel" | i18n }}
diff --git a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts
index 94329d2fde9..8b69a8956e3 100644
--- a/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts
+++ b/apps/web/src/app/billing/organizations/change-plan-dialog.component.ts
@@ -138,7 +138,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
clientOwnerEmail: ["", [Validators.email]],
plan: [this.plan],
productTier: [this.productTier],
- planInterval: [1],
+ // planInterval: [1],
});
planType: string;
@@ -146,6 +146,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
selectedInterval: number = 1;
planIntervals = PlanInterval;
passwordManagerPlans: PlanResponse[];
+ secretsManagerPlans: PlanResponse[];
organization: Organization;
sub: OrganizationSubscriptionResponse;
billing: BillingResponse;
@@ -188,6 +189,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
if (!this.selfHosted) {
const plans = await this.apiService.getPlans();
this.passwordManagerPlans = plans.data.filter((plan) => !!plan.PasswordManager);
+ this.secretsManagerPlans = plans.data.filter((plan) => !!plan.SecretsManager);
if (
this.productTier === ProductTierType.Enterprise ||
@@ -230,12 +232,6 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
selected: false,
},
];
-
- this.formGroup
- .get("planInterval")
- .valueChanges.pipe(takeUntil(this.destroy$))
- .subscribe((value: number) => (this.selectedInterval = value));
-
this.discountPercentageFromSub = this.sub?.customerDiscount?.percentOff;
this.setInitialPlanSelection();
@@ -243,15 +239,42 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}
setInitialPlanSelection() {
- this.selectPlan(this.getPlanByType(ProductTierType.Enterprise));
+ if (
+ this.organization.useSecretsManager &&
+ this.currentPlan.productTier == ProductTierType.Free
+ ) {
+ this.selectPlan(this.getPlanByType(ProductTierType.Teams));
+ } else {
+ this.selectPlan(this.getPlanByType(ProductTierType.Enterprise));
+ }
}
getPlanByType(productTier: ProductTierType) {
return this.selectableProducts.find((product) => product.productTier === productTier);
}
+ isSecretsManagerTrial(): boolean {
+ return (
+ this.sub?.subscription?.items?.some((item) =>
+ this.sub?.customerDiscount?.appliesTo?.includes(item.productId),
+ ) ?? false
+ );
+ }
+
planTypeChanged() {
- this.selectPlan(this.getPlanByType(ProductTierType.Enterprise));
+ if (
+ this.organization.useSecretsManager &&
+ this.currentPlan.productTier == ProductTierType.Free
+ ) {
+ this.selectPlan(this.getPlanByType(ProductTierType.Teams));
+ } else {
+ this.selectPlan(this.getPlanByType(ProductTierType.Enterprise));
+ }
+ }
+
+ updateInterval(event: number) {
+ this.selectedInterval = event;
+ this.planTypeChanged();
}
protected getPlanIntervals() {
@@ -270,7 +293,9 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
protected getPlanCardContainerClasses(plan: PlanResponse, index: number) {
let cardState: PlanCardState;
- if (plan == this.selectedPlan) {
+ if (plan == this.currentPlan) {
+ cardState = PlanCardState.Disabled;
+ } else if (plan == this.selectedPlan) {
cardState = PlanCardState.Selected;
} else if (
this.selectedInterval === PlanInterval.Monthly &&
@@ -283,36 +308,19 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
switch (cardState) {
case PlanCardState.Selected: {
- if (this.currentPlan.productTier === ProductTierType.Teams) {
- return [
- "tw-group",
- "tw-cursor-pointer",
- "tw-block",
- "tw-rounded",
- "tw-w-1/2",
- "tw-border",
- "tw-border-solid",
- "tw-border-primary-600",
- "hover:tw-border-primary-700",
- "focus:tw-border-2",
- "focus:tw-border-primary-700",
- "focus:tw-rounded-lg",
- ];
- } else {
- return [
- "tw-group",
- "tw-cursor-pointer",
- "tw-block",
- "tw-rounded",
- "tw-border",
- "tw-border-solid",
- "tw-border-primary-600",
- "hover:tw-border-primary-700",
- "focus:tw-border-2",
- "focus:tw-border-primary-700",
- "focus:tw-rounded-lg",
- ];
- }
+ return [
+ "tw-group",
+ "tw-cursor-pointer",
+ "tw-block",
+ "tw-rounded",
+ "tw-border",
+ "tw-border-solid",
+ "tw-border-primary-600",
+ "hover:tw-border-primary-700",
+ "focus:tw-border-2",
+ "focus:tw-border-primary-700",
+ "focus:tw-rounded-lg",
+ ];
}
case PlanCardState.NotSelected: {
return [
@@ -336,10 +344,6 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
"tw-text-muted",
"tw-block",
"tw-rounded",
- "tw-border",
- "tw-border-solid",
- "tw-border-1",
- "tw-border-secondary-300",
];
}
}
@@ -369,6 +373,10 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
);
}
+ get selectedSecretsManagerPlan() {
+ return this.secretsManagerPlans.find((plan) => plan.type === this.selectedPlan.type);
+ }
+
get selectedPlanInterval() {
return this.selectedPlan.isAnnual ? "year" : "month";
}
@@ -397,9 +405,37 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
this.planIsEnabled(plan),
);
+ if (
+ this.currentPlan.productTier === ProductTierType.Free &&
+ this.selectedInterval === PlanInterval.Monthly &&
+ !this.organization.useSecretsManager
+ ) {
+ const familyPlan = this.passwordManagerPlans.find(
+ (plan) => plan.productTier == ProductTierType.Families,
+ );
+ result.push(familyPlan);
+ }
+
+ if (
+ this.organization.useSecretsManager &&
+ this.currentPlan.productTier === ProductTierType.Free
+ ) {
+ const familyPlanIndex = result.findIndex(
+ (plan) => plan.productTier === ProductTierType.Families,
+ );
+
+ if (familyPlanIndex !== -1) {
+ result.splice(familyPlanIndex, 1);
+ }
+ }
+
+ if (this.currentPlan.productTier !== ProductTierType.Free) {
+ result.push(this.currentPlan);
+ }
+
result.sort((planA, planB) => planA.displaySortOrder - planB.displaySortOrder);
- return result.reverse();
+ return result;
}
get selectablePlans() {
@@ -414,7 +450,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}
passwordManagerSeatTotal(plan: PlanResponse): number {
- if (!plan.PasswordManager.hasAdditionalSeatsOption) {
+ if (!plan.PasswordManager.hasAdditionalSeatsOption || this.isSecretsManagerTrial()) {
return 0;
}
@@ -422,6 +458,33 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
return result;
}
+ secretsManagerSeatTotal(plan: PlanResponse, seats: number): number {
+ if (!plan.SecretsManager.hasAdditionalSeatsOption) {
+ return 0;
+ }
+
+ return plan.SecretsManager.seatPrice * Math.abs(seats || 0);
+ }
+
+ additionalStorageTotal(plan: PlanResponse): number {
+ if (!plan.PasswordManager.hasAdditionalStorageOption) {
+ return 0;
+ }
+
+ return (
+ plan.PasswordManager.additionalStoragePricePerGb *
+ Math.abs(this.organization.maxStorageGb || 0)
+ );
+ }
+
+ additionalServiceAccountTotal(plan: PlanResponse): number {
+ if (!plan.SecretsManager.hasAdditionalServiceAccountOption || this.additionalServiceAccount) {
+ return 0;
+ }
+
+ return plan.SecretsManager.additionalPricePerServiceAccount * this.additionalServiceAccount;
+ }
+
get passwordManagerSubtotal() {
let subTotal = this.selectedPlan.PasswordManager.basePrice;
if (this.selectedPlan.PasswordManager.hasAdditionalSeatsOption) {
@@ -433,13 +496,37 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
return subTotal - this.discount;
}
+ get secretsManagerSubtotal() {
+ const plan = this.selectedSecretsManagerPlan;
+
+ if (!this.organization.useSecretsManager) {
+ return 0;
+ }
+
+ return (
+ plan.SecretsManager.basePrice +
+ this.secretsManagerSeatTotal(plan, this.sub?.smSeats) +
+ this.additionalServiceAccountTotal(plan)
+ );
+ }
+
get taxCharges() {
return this.taxComponent != null && this.taxComponent.taxRate != null
? (this.taxComponent.taxRate / 100) * this.passwordManagerSubtotal
: 0;
}
+ get passwordManagerSeats() {
+ if (this.selectedPlan.productTier === ProductTierType.Families) {
+ return this.selectedPlan.PasswordManager.baseSeats;
+ }
+ return this.organization.seats;
+ }
+
get total() {
+ if (this.organization.useSecretsManager) {
+ return this.passwordManagerSubtotal + this.secretsManagerSubtotal + this.taxCharges || 0;
+ }
return this.passwordManagerSubtotal + this.taxCharges || 0;
}
@@ -447,6 +534,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
return this.selectablePlans.some((plan) => plan.type === PlanType.TeamsStarter);
}
+ get additionalServiceAccount() {
+ const baseServiceAccount = this.selectedPlan.SecretsManager?.baseServiceAccount || 0;
+ const usedServiceAccounts = this.sub?.smServiceAccounts || 0;
+
+ const additionalServiceAccounts = baseServiceAccount - usedServiceAccounts;
+
+ return additionalServiceAccounts <= 0 ? Math.abs(additionalServiceAccounts) : 0;
+ }
+
changedProduct() {
const selectedPlan = this.selectablePlans[0];
@@ -552,6 +648,9 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
request.billingAddressPostalCode = this.taxComponent.taxFormGroup?.value.postalCode;
}
+ // Secrets Manager
+ this.buildSecretsManagerRequest(request);
+
if (this.upgradeRequiresPaymentMethod || this.showPayment) {
const tokenResult = await this.paymentComponent.createPaymentToken();
const paymentRequest = new PaymentRequest();
@@ -593,6 +692,22 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
return text;
}
+ private buildSecretsManagerRequest(request: OrganizationUpgradeRequest): void {
+ request.useSecretsManager = this.organization.useSecretsManager;
+ if (!this.organization.useSecretsManager) {
+ return;
+ }
+
+ if (
+ this.selectedPlan.SecretsManager.hasAdditionalSeatsOption &&
+ this.currentPlan.productTier === ProductTierType.Free
+ ) {
+ request.additionalSmSeats = this.organization.seats;
+ } else {
+ request.additionalSmSeats = this.sub?.smSeats;
+ }
+ }
+
private upgradeFlowPrefillForm() {
if (this.acceptingSponsorship) {
this.formGroup.controls.productTier.setValue(ProductTierType.Families);
diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json
index 108807b153f..a445e099019 100644
--- a/apps/web/src/locales/en/messages.json
+++ b/apps/web/src/locales/en/messages.json
@@ -8954,5 +8954,56 @@
},
"additionalStorageGbMessage": {
"message": "GB additional storage"
+ },
+ "premiumAccounts": {
+ "message": "6 premium accounts"
+ },
+ "unlimitedSharing": {
+ "message": "Unlimited sharing"
+ },
+ "unlimitedCollections": {
+ "message": "Unlimited collections"
+ },
+ "secureDataSharing": {
+ "message": "Secure data sharing"
+ },
+ "eventLogMonitoring": {
+ "message": "Event log monitoring"
+ },
+ "directoryIntegration": {
+ "message": "Directory integration"
+ },
+ "passwordLessSso": {
+ "message": "PasswordLess SSO"
+ },
+ "accountRecovery": {
+ "message": "Account recovery"
+ },
+ "customRoles": {
+ "message": "Custom roles"
+ },
+ "unlimitedSecretsStorage": {
+ "message": "Unlimited secrets storage"
+ },
+ "unlimitedUsers": {
+ "message": "Unlimited users"
+ },
+ "UpTo50MachineAccounts": {
+ "message": "Up to 50 machine accounts"
+ },
+ "UpTo20MachineAccounts": {
+ "message": "Up to 20 machine accounts"
+ },
+ "current": {
+ "message": "Current"
+ },
+ "secretsManagerSubInfo": {
+ "message": "Your Secrets Manager subscription will upgrade base on the plan selected"
+ },
+ "bitwardenPasswordManager": {
+ "message": "Bitwarden Password Manager"
+ },
+ "secretsManagerWithFreePasswordManagerInfo": {
+ "message": "Your complementary one year Password Manager subscription will upgrade to the selected plan. You will not be charged until the complimentary period is over."
}
}
From 2ee51589ced0771b5dcbf17a3f1c4a12fa5dfaac Mon Sep 17 00:00:00 2001
From: Jordan Aasen <166539328+jaasen-livefront@users.noreply.github.com>
Date: Fri, 23 Aug 2024 09:13:25 -0700
Subject: [PATCH 02/11] migrate secrets manager toasts to CL toastService
(#10677)
---
.../dialog/project-delete-dialog.component.ts | 9 +++--
.../dialog/project-dialog.component.ts | 25 +++++++++-----
.../guards/project-access.guard.spec.ts | 14 +++++---
.../projects/guards/project-access.guard.ts | 14 ++++----
.../project/project-people.component.ts | 13 +++----
.../project-service-accounts.component.ts | 12 ++++---
.../secrets/dialog/secret-delete.component.ts | 9 +++--
.../secrets/dialog/secret-dialog.component.ts | 34 ++++++++++++++-----
.../access/access-tokens.component.ts | 19 +++++++----
...service-account-delete-dialog.component.ts | 9 +++--
.../service-account-dialog.component.ts | 19 +++++++----
.../service-account-access.guard.spec.ts | 18 +++++-----
.../guards/service-account-access.guard.ts | 14 ++++----
.../service-account-people.component.ts | 13 +++----
.../service-account-projects.component.ts | 12 ++++---
.../service-accounts-list.component.ts | 13 +++----
.../settings/porting/sm-export.component.ts | 9 +++--
.../shared/projects-list.component.ts | 13 +++----
.../shared/secrets-list.component.ts | 23 +++++++------
.../dialog/secret-hard-delete.component.ts | 8 ++++-
.../trash/dialog/secret-restore.component.ts | 8 ++++-
21 files changed, 194 insertions(+), 114 deletions(-)
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-delete-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-delete-dialog.component.ts
index 1805b3b42cd..feb366823cb 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-delete-dialog.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-delete-dialog.component.ts
@@ -10,7 +10,7 @@ import {
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { DialogService } from "@bitwarden/components";
+import { DialogService, ToastService } from "@bitwarden/components";
import { ProjectListView } from "../../models/view/project-list.view";
import {
@@ -39,6 +39,7 @@ export class ProjectDeleteDialogComponent implements OnInit {
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private dialogService: DialogService,
+ private toastService: ToastService,
) {}
ngOnInit(): void {
@@ -84,7 +85,11 @@ export class ProjectDeleteDialogComponent implements OnInit {
}
const message = this.data.projects.length === 1 ? "deleteProjectToast" : "deleteProjectsToast";
- this.platformUtilsService.showToast("success", null, this.i18nService.t(message));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t(message),
+ });
}
openBulkStatusDialog(bulkStatusResults: BulkOperationStatus[]) {
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts
index d30d5f664e2..09f3d9573ac 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/dialog/project-dialog.component.ts
@@ -5,7 +5,7 @@ import { Router } from "@angular/router";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { BitValidators } from "@bitwarden/components";
+import { BitValidators, ToastService } from "@bitwarden/components";
import { ProjectView } from "../../models/view/project.view";
import { ProjectService } from "../../projects/project.service";
@@ -41,6 +41,7 @@ export class ProjectDialogComponent implements OnInit {
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private router: Router,
+ private toastService: ToastService,
) {}
async ngOnInit() {
@@ -65,11 +66,11 @@ export class ProjectDialogComponent implements OnInit {
submit = async () => {
if (!this.data.organizationEnabled) {
- this.platformUtilsService.showToast(
- "error",
- null,
- this.i18nService.t("projectsCannotCreate"),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: null,
+ message: this.i18nService.t("projectsCannotCreate"),
+ });
return;
}
@@ -92,13 +93,21 @@ export class ProjectDialogComponent implements OnInit {
private async createProject(projectView: ProjectView) {
const newProject = await this.projectService.create(this.data.organizationId, projectView);
- this.platformUtilsService.showToast("success", null, this.i18nService.t("projectCreated"));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("projectCreated"),
+ });
return newProject;
}
private async updateProject(projectView: ProjectView) {
await this.projectService.update(this.data.organizationId, projectView);
- this.platformUtilsService.showToast("success", null, this.i18nService.t("projectSaved"));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("projectSaved"),
+ });
}
private getProjectView() {
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts
index 84bc1483fd1..631f6409748 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.spec.ts
@@ -7,7 +7,7 @@ import { MockProxy, mock } from "jest-mock-extended";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
-import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { ToastService } from "@bitwarden/components";
import { RouterService } from "../../../../../../../apps/web/src/app/core/router.service";
import { ProjectView } from "../../models/view/project.view";
@@ -30,7 +30,7 @@ describe("Project Redirect Guard", () => {
let routerService: MockProxy;
let projectServiceMock: MockProxy;
let i18nServiceMock: MockProxy;
- let platformUtilsService: MockProxy;
+ let toastService: MockProxy;
let router: Router;
const smOrg1 = { id: "123", canAccessSecretsManager: true } as Organization;
@@ -49,7 +49,7 @@ describe("Project Redirect Guard", () => {
routerService = mock();
projectServiceMock = mock();
i18nServiceMock = mock();
- platformUtilsService = mock();
+ toastService = mock();
TestBed.configureTestingModule({
imports: [
@@ -74,7 +74,7 @@ describe("Project Redirect Guard", () => {
{ provide: RouterService, useValue: routerService },
{ provide: ProjectService, useValue: projectServiceMock },
{ provide: I18nService, useValue: i18nServiceMock },
- { provide: PlatformUtilsService, useValue: platformUtilsService },
+ { provide: ToastService, useValue: toastService },
],
});
@@ -114,7 +114,11 @@ describe("Project Redirect Guard", () => {
// Act
await router.navigateByUrl("sm/123/projects/123");
// Assert
- expect(platformUtilsService.showToast).toHaveBeenCalledWith("error", null, "Project not found");
+ expect(toastService.showToast).toHaveBeenCalledWith({
+ variant: "error",
+ title: null,
+ message: "Project not found",
+ });
expect(router.url).toBe("/sm/123/projects");
});
});
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.ts
index 6c08fcc3aa7..1f694d6999a 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/guards/project-access.guard.ts
@@ -2,7 +2,7 @@ import { inject } from "@angular/core";
import { ActivatedRouteSnapshot, CanActivateFn, createUrlTreeFromSnapshot } from "@angular/router";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
-import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { ToastService } from "@bitwarden/components";
import { ProjectService } from "../project.service";
@@ -11,7 +11,7 @@ import { ProjectService } from "../project.service";
*/
export const projectAccessGuard: CanActivateFn = async (route: ActivatedRouteSnapshot) => {
const projectService = inject(ProjectService);
- const platformUtilsService = inject(PlatformUtilsService);
+ const toastService = inject(ToastService);
const i18nService = inject(I18nService);
try {
@@ -20,11 +20,11 @@ export const projectAccessGuard: CanActivateFn = async (route: ActivatedRouteSna
return true;
}
} catch {
- platformUtilsService.showToast(
- "error",
- null,
- i18nService.t("notFound", i18nService.t("project")),
- );
+ toastService.showToast({
+ variant: "error",
+ title: null,
+ message: i18nService.t("notFound", i18nService.t("project")),
+ });
return createUrlTreeFromSnapshot(route, ["/sm", route.params.organizationId, "projects"]);
}
return createUrlTreeFromSnapshot(route, ["/sm", route.params.organizationId, "projects"]);
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts
index 0b0e13fe1f5..2500416880b 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-people.component.ts
@@ -7,7 +7,7 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
-import { DialogService } from "@bitwarden/components";
+import { DialogService, ToastService } from "@bitwarden/components";
import { AccessPolicySelectorService } from "../../shared/access-policies/access-policy-selector/access-policy-selector.service";
import {
@@ -73,6 +73,7 @@ export class ProjectPeopleComponent implements OnInit, OnDestroy {
private i18nService: I18nService,
private accessPolicySelectorService: AccessPolicySelectorService,
private logService: LogService,
+ private toastService: ToastService,
) {}
ngOnInit(): void {
@@ -129,11 +130,11 @@ export class ProjectPeopleComponent implements OnInit, OnDestroy {
if (showAccessRemovalWarning) {
await this.router.navigate(["sm", this.organizationId, "projects"]);
}
- this.platformUtilsService.showToast(
- "success",
- null,
- this.i18nService.t("projectAccessUpdated"),
- );
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("projectAccessUpdated"),
+ });
} catch (e) {
this.validationService.showError(e);
this.setSelected(this.currentAccessPolicies);
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts
index 1069033b57d..4ac14b3b362 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/projects/project/project-service-accounts.component.ts
@@ -6,6 +6,7 @@ import { combineLatest, Subject, switchMap, takeUntil } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
+import { ToastService } from "@bitwarden/components";
import { ProjectServiceAccountsAccessPoliciesView } from "../../models/view/access-policies/project-service-accounts-access-policies.view";
import {
@@ -64,6 +65,7 @@ export class ProjectServiceAccountsComponent implements OnInit, OnDestroy {
private accessPolicyService: AccessPolicyService,
private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService,
+ private toastService: ToastService,
) {}
ngOnInit(): void {
@@ -104,11 +106,11 @@ export class ProjectServiceAccountsComponent implements OnInit, OnDestroy {
this.items = this.getItems(this.potentialGrantees, updatedView);
this.setSelected(updatedView);
- this.platformUtilsService.showToast(
- "success",
- null,
- this.i18nService.t("projectAccessUpdated"),
- );
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("projectAccessUpdated"),
+ });
} catch (e) {
this.validationService.showError(e);
this.setSelected(this.currentAccessPolicies);
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-delete.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-delete.component.ts
index 0b536c5cee2..10d58bc2ea5 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-delete.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-delete.component.ts
@@ -3,7 +3,7 @@ import { Component, Inject } from "@angular/core";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { DialogService } from "@bitwarden/components";
+import { DialogService, ToastService } from "@bitwarden/components";
import { SecretListView } from "../../models/view/secret-list.view";
import {
@@ -28,6 +28,7 @@ export class SecretDeleteDialogComponent {
private platformUtilsService: PlatformUtilsService,
@Inject(DIALOG_DATA) private data: SecretDeleteOperation,
private dialogService: DialogService,
+ private toastService: ToastService,
) {}
showSoftDeleteSecretWarning = this.data.secrets.length === 1;
@@ -51,7 +52,11 @@ export class SecretDeleteDialogComponent {
const message =
this.data.secrets.length === 1 ? "softDeleteSuccessToast" : "softDeletesSuccessToast";
- this.platformUtilsService.showToast("success", null, this.i18nService.t(message));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t(message),
+ });
this.dialogRef.close(true);
};
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts
index b9f6adc3ae7..b656570a54c 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/secrets/dialog/secret-dialog.component.ts
@@ -7,7 +7,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { Utils } from "@bitwarden/common/platform/misc/utils";
-import { DialogService, BitValidators } from "@bitwarden/components";
+import { DialogService, BitValidators, ToastService } from "@bitwarden/components";
import { SecretAccessPoliciesView } from "../../models/view/access-policies/secret-access-policies.view";
import { ProjectListView } from "../../models/view/project-list.view";
@@ -97,6 +97,7 @@ export class SecretDialogComponent implements OnInit, OnDestroy {
private organizationService: OrganizationService,
private accessPolicyService: AccessPolicyService,
private accessPolicySelectorService: AccessPolicySelectorService,
+ private toastService: ToastService,
) {}
get title() {
@@ -139,7 +140,11 @@ export class SecretDialogComponent implements OnInit, OnDestroy {
submit = async () => {
if (!this.data.organizationEnabled) {
- this.platformUtilsService.showToast("error", null, this.i18nService.t("secretsCannotCreate"));
+ this.toastService.showToast({
+ variant: "error",
+ title: null,
+ message: this.i18nService.t("secretsCannotCreate"),
+ });
return;
}
@@ -318,7 +323,11 @@ export class SecretDialogComponent implements OnInit, OnDestroy {
secretAccessPoliciesView: SecretAccessPoliciesView,
) {
await this.secretService.create(this.data.organizationId, secretView, secretAccessPoliciesView);
- this.platformUtilsService.showToast("success", null, this.i18nService.t("secretCreated"));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("secretCreated"),
+ });
}
private getNewProjectView() {
@@ -333,7 +342,11 @@ export class SecretDialogComponent implements OnInit, OnDestroy {
secretAccessPoliciesView: SecretAccessPoliciesView,
) {
await this.secretService.update(this.data.organizationId, secretView, secretAccessPoliciesView);
- this.platformUtilsService.showToast("success", null, this.i18nService.t("secretEdited"));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("secretEdited"),
+ });
}
private getSecretView() {
@@ -417,11 +430,14 @@ export class SecretDialogComponent implements OnInit, OnDestroy {
this.formGroup.markAllAsTouched();
if (this.formGroup.invalid && this.tabIndex !== SecretDialogTabType.NameValuePair) {
- this.platformUtilsService.showToast(
- "error",
- null,
- this.i18nService.t("fieldOnTabRequiresAttention", this.i18nService.t("nameValuePair")),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: null,
+ message: this.i18nService.t(
+ "fieldOnTabRequiresAttention",
+ this.i18nService.t("nameValuePair"),
+ ),
+ });
}
return this.formGroup.invalid;
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts
index 2c1b6dc4932..25ad93706ab 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/access/access-tokens.component.ts
@@ -12,7 +12,7 @@ import {
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { DialogService } from "@bitwarden/components";
+import { DialogService, ToastService } from "@bitwarden/components";
import { openUserVerificationPrompt } from "@bitwarden/web-vault/app/auth/shared/components/user-verification";
import { ServiceAccountView } from "../../models/view/service-account.view";
@@ -39,6 +39,7 @@ export class AccessTokenComponent implements OnInit, OnDestroy {
private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService,
private serviceAccountService: ServiceAccountService,
+ private toastService: ToastService,
) {}
ngOnInit() {
@@ -74,11 +75,11 @@ export class AccessTokenComponent implements OnInit, OnDestroy {
protected async revoke(tokens: AccessTokenView[]) {
if (!tokens?.length) {
- this.platformUtilsService.showToast(
- "error",
- null,
- this.i18nService.t("noAccessTokenSelected"),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: null,
+ message: this.i18nService.t("noAccessTokenSelected"),
+ });
return;
}
@@ -91,7 +92,11 @@ export class AccessTokenComponent implements OnInit, OnDestroy {
tokens.map((t) => t.id),
);
- this.platformUtilsService.showToast("success", null, this.i18nService.t("accessTokenRevoked"));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("accessTokenRevoked"),
+ });
}
protected openNewAccessTokenDialog() {
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-delete-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-delete-dialog.component.ts
index b31ef03d12d..c44daced812 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-delete-dialog.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-delete-dialog.component.ts
@@ -10,7 +10,7 @@ import {
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { DialogService } from "@bitwarden/components";
+import { DialogService, ToastService } from "@bitwarden/components";
import { ServiceAccountView } from "../../models/view/service-account.view";
import {
@@ -39,6 +39,7 @@ export class ServiceAccountDeleteDialogComponent {
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
private dialogService: DialogService,
+ private toastService: ToastService,
) {}
get title() {
@@ -81,7 +82,11 @@ export class ServiceAccountDeleteDialogComponent {
this.data.serviceAccounts.length === 1
? "deleteMachineAccountToast"
: "deleteMachineAccountsToast";
- this.platformUtilsService.showToast("success", null, this.i18nService.t(message));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t(message),
+ });
}
openBulkStatusDialog(bulkStatusResults: BulkOperationStatus[]) {
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts
index 0ae72608ad3..27e9152b474 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/dialog/service-account-dialog.component.ts
@@ -4,7 +4,7 @@ import { FormControl, FormGroup, Validators } from "@angular/forms";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { BitValidators } from "@bitwarden/components";
+import { BitValidators, ToastService } from "@bitwarden/components";
import { ServiceAccountView } from "../../models/view/service-account.view";
import { ServiceAccountService } from "../service-account.service";
@@ -43,6 +43,7 @@ export class ServiceAccountDialogComponent implements OnInit {
private serviceAccountService: ServiceAccountService,
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
+ private toastService: ToastService,
) {}
async ngOnInit() {
@@ -64,11 +65,11 @@ export class ServiceAccountDialogComponent implements OnInit {
submit = async () => {
if (!this.data.organizationEnabled) {
- this.platformUtilsService.showToast(
- "error",
- null,
- this.i18nService.t("machineAccountsCannotCreate"),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: null,
+ message: this.i18nService.t("machineAccountsCannotCreate"),
+ });
return;
}
@@ -93,7 +94,11 @@ export class ServiceAccountDialogComponent implements OnInit {
serviceAccountMessage = this.i18nService.t("machineAccountUpdated");
}
- this.platformUtilsService.showToast("success", null, serviceAccountMessage);
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: serviceAccountMessage,
+ });
this.dialogRef.close();
};
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts
index 956935ac6ac..ebd00a83ea5 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.spec.ts
@@ -7,7 +7,7 @@ import { MockProxy, mock } from "jest-mock-extended";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
-import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { ToastService } from "@bitwarden/components";
import { RouterService } from "../../../../../../../../clients/apps/web/src/app/core/router.service";
import { ServiceAccountView } from "../../models/view/service-account.view";
@@ -30,7 +30,7 @@ describe("Service account Redirect Guard", () => {
let routerService: MockProxy;
let serviceAccountServiceMock: MockProxy;
let i18nServiceMock: MockProxy;
- let platformUtilsService: MockProxy;
+ let toastService: MockProxy;
let router: Router;
const smOrg1 = { id: "123", canAccessSecretsManager: true } as Organization;
@@ -45,7 +45,7 @@ describe("Service account Redirect Guard", () => {
routerService = mock();
serviceAccountServiceMock = mock();
i18nServiceMock = mock();
- platformUtilsService = mock();
+ toastService = mock();
TestBed.configureTestingModule({
imports: [
@@ -70,7 +70,7 @@ describe("Service account Redirect Guard", () => {
{ provide: RouterService, useValue: routerService },
{ provide: ServiceAccountService, useValue: serviceAccountServiceMock },
{ provide: I18nService, useValue: i18nServiceMock },
- { provide: PlatformUtilsService, useValue: platformUtilsService },
+ { provide: ToastService, useValue: toastService },
],
});
@@ -112,11 +112,11 @@ describe("Service account Redirect Guard", () => {
// Act
await router.navigateByUrl("sm/123/machine-accounts/123");
// Assert
- expect(platformUtilsService.showToast).toHaveBeenCalledWith(
- "error",
- null,
- "Service account not found",
- );
+ expect(toastService.showToast).toHaveBeenCalledWith({
+ variant: "error",
+ title: null,
+ message: "Service account not found",
+ });
expect(router.url).toBe("/sm/123/machine-accounts");
});
});
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.ts
index b72fc5a1fe2..0aa83aa0e96 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/guards/service-account-access.guard.ts
@@ -2,7 +2,7 @@ import { inject } from "@angular/core";
import { ActivatedRouteSnapshot, CanActivateFn, createUrlTreeFromSnapshot } from "@angular/router";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
-import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { ToastService } from "@bitwarden/components";
import { ServiceAccountService } from "../service-account.service";
@@ -11,7 +11,7 @@ import { ServiceAccountService } from "../service-account.service";
*/
export const serviceAccountAccessGuard: CanActivateFn = async (route: ActivatedRouteSnapshot) => {
const serviceAccountService = inject(ServiceAccountService);
- const platformUtilsService = inject(PlatformUtilsService);
+ const toastService = inject(ToastService);
const i18nService = inject(I18nService);
try {
@@ -23,11 +23,11 @@ export const serviceAccountAccessGuard: CanActivateFn = async (route: ActivatedR
return true;
}
} catch {
- platformUtilsService.showToast(
- "error",
- null,
- i18nService.t("notFound", i18nService.t("machineAccount")),
- );
+ toastService.showToast({
+ variant: "error",
+ title: null,
+ message: i18nService.t("notFound", i18nService.t("machineAccount")),
+ });
return createUrlTreeFromSnapshot(route, [
"/sm",
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts
index 46033688826..58675b15b37 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/people/service-account-people.component.ts
@@ -6,7 +6,7 @@ import { combineLatest, Subject, switchMap, takeUntil } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
-import { DialogService } from "@bitwarden/components";
+import { DialogService, ToastService } from "@bitwarden/components";
import { ServiceAccountPeopleAccessPoliciesView } from "../../models/view/access-policies/service-account-people-access-policies.view";
import { AccessPolicySelectorService } from "../../shared/access-policies/access-policy-selector/access-policy-selector.service";
@@ -71,6 +71,7 @@ export class ServiceAccountPeopleComponent implements OnInit, OnDestroy {
private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService,
private accessPolicySelectorService: AccessPolicySelectorService,
+ private toastService: ToastService,
) {}
ngOnInit(): void {
@@ -126,11 +127,11 @@ export class ServiceAccountPeopleComponent implements OnInit, OnDestroy {
this.currentAccessPolicies = convertToAccessPolicyItemViews(peoplePoliciesViews);
- this.platformUtilsService.showToast(
- "success",
- null,
- this.i18nService.t("machineAccountAccessUpdated"),
- );
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("machineAccountAccessUpdated"),
+ });
} catch (e) {
this.validationService.showError(e);
this.setSelected(this.currentAccessPolicies);
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts
index 358a152b6f3..2ee95848012 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/projects/service-account-projects.component.ts
@@ -6,6 +6,7 @@ import { combineLatest, Subject, switchMap, takeUntil } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { ValidationService } from "@bitwarden/common/platform/abstractions/validation.service";
+import { ToastService } from "@bitwarden/components";
import { ServiceAccountGrantedPoliciesView } from "../../models/view/access-policies/service-account-granted-policies.view";
import {
@@ -63,6 +64,7 @@ export class ServiceAccountProjectsComponent implements OnInit, OnDestroy {
private accessPolicyService: AccessPolicyService,
private platformUtilsService: PlatformUtilsService,
private i18nService: I18nService,
+ private toastService: ToastService,
) {}
ngOnInit(): void {
@@ -103,11 +105,11 @@ export class ServiceAccountProjectsComponent implements OnInit, OnDestroy {
this.currentAccessPolicies = convertGrantedPoliciesToAccessPolicyItemViews(grantedViews);
- this.platformUtilsService.showToast(
- "success",
- null,
- this.i18nService.t("serviceAccountAccessUpdated"),
- );
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("serviceAccountAccessUpdated"),
+ });
} catch (e) {
this.validationService.showError(e);
this.setSelected(this.currentAccessPolicies);
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.ts
index 3f39b9ebb94..75edd0f0932 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/service-accounts/service-accounts-list.component.ts
@@ -4,7 +4,7 @@ import { Subject, takeUntil } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { TableDataSource } from "@bitwarden/components";
+import { TableDataSource, ToastService } from "@bitwarden/components";
import {
ServiceAccountSecretsDetailsView,
@@ -47,6 +47,7 @@ export class ServiceAccountsListComponent implements OnDestroy {
constructor(
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
+ private toastService: ToastService,
) {
this.selection.changed
.pipe(takeUntil(this.destroy$))
@@ -85,11 +86,11 @@ export class ServiceAccountsListComponent implements OnDestroy {
this.serviceAccounts.filter((sa) => this.selection.isSelected(sa.id)),
);
} else {
- this.platformUtilsService.showToast(
- "error",
- this.i18nService.t("errorOccurred"),
- this.i18nService.t("nothingSelected"),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: this.i18nService.t("errorOccurred"),
+ message: this.i18nService.t("nothingSelected"),
+ });
}
}
}
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts
index 9fa75fed6ed..713a93b643d 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/settings/porting/sm-export.component.ts
@@ -8,7 +8,7 @@ import { FileDownloadService } from "@bitwarden/common/platform/abstractions/fil
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";
-import { DialogService } from "@bitwarden/components";
+import { DialogService, ToastService } from "@bitwarden/components";
import { openUserVerificationPrompt } from "@bitwarden/web-vault/app/auth/shared/components/user-verification";
import { SecretsManagerPortingApiService } from "../services/sm-porting-api.service";
@@ -44,6 +44,7 @@ export class SecretsManagerExportComponent implements OnInit, OnDestroy {
private logService: LogService,
private dialogService: DialogService,
private secretsManagerApiService: SecretsManagerPortingApiService,
+ private toastService: ToastService,
) {}
async ngOnInit() {
@@ -85,7 +86,11 @@ export class SecretsManagerExportComponent implements OnInit, OnDestroy {
const exportData = await this.secretsManagerApiService.export(this.orgId);
await this.downloadFile(exportData, fileExtension);
- this.platformUtilsService.showToast("success", null, this.i18nService.t("dataExportSuccess"));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t("dataExportSuccess"),
+ });
}
private async downloadFile(data: string, format: string) {
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.ts
index 7039b0a9920..8c6a5e97dc4 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/projects-list.component.ts
@@ -4,7 +4,7 @@ import { map } from "rxjs";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
-import { TableDataSource } from "@bitwarden/components";
+import { TableDataSource, ToastService } from "@bitwarden/components";
import { ProjectListView } from "../models/view/project-list.view";
@@ -43,6 +43,7 @@ export class ProjectsListComponent {
constructor(
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
+ private toastService: ToastService,
) {}
isAllSelected() {
@@ -72,11 +73,11 @@ export class ProjectsListComponent {
this.projects.filter((project) => this.selection.isSelected(project.id)),
);
} else {
- this.platformUtilsService.showToast(
- "error",
- this.i18nService.t("errorOccurred"),
- this.i18nService.t("nothingSelected"),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: this.i18nService.t("errorOccurred"),
+ message: this.i18nService.t("nothingSelected"),
+ });
}
}
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.ts
index 62c4a43379e..81c96c6b961 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/secrets-list.component.ts
@@ -5,7 +5,7 @@ import { Subject, takeUntil } from "rxjs";
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";
-import { TableDataSource } from "@bitwarden/components";
+import { TableDataSource, ToastService } from "@bitwarden/components";
import { SecretListView } from "../models/view/secret-list.view";
import { SecretService } from "../secrets/secret.service";
@@ -53,6 +53,7 @@ export class SecretsListComponent implements OnDestroy {
constructor(
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
+ private toastService: ToastService,
) {
this.selection.changed
.pipe(takeUntil(this.destroy$))
@@ -87,11 +88,11 @@ export class SecretsListComponent implements OnDestroy {
this.secrets.filter((secret) => this.selection.isSelected(secret.id)),
);
} else {
- this.platformUtilsService.showToast(
- "error",
- this.i18nService.t("errorOccurred"),
- this.i18nService.t("nothingSelected"),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: this.i18nService.t("errorOccurred"),
+ message: this.i18nService.t("nothingSelected"),
+ });
}
}
@@ -99,11 +100,11 @@ export class SecretsListComponent implements OnDestroy {
if (this.selection.selected.length >= 1) {
this.restoreSecretsEvent.emit(this.selection.selected);
} else {
- this.platformUtilsService.showToast(
- "error",
- this.i18nService.t("errorOccurred"),
- this.i18nService.t("nothingSelected"),
- );
+ this.toastService.showToast({
+ variant: "error",
+ title: this.i18nService.t("errorOccurred"),
+ message: this.i18nService.t("nothingSelected"),
+ });
}
}
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-hard-delete.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-hard-delete.component.ts
index c0bff802a22..9e9d41a29b9 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-hard-delete.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-hard-delete.component.ts
@@ -3,6 +3,7 @@ import { Component, Inject } from "@angular/core";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { ToastService } from "@bitwarden/components";
import { SecretService } from "../../secrets/secret.service";
@@ -21,6 +22,7 @@ export class SecretHardDeleteDialogComponent {
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
@Inject(DIALOG_DATA) public data: SecretHardDeleteOperation,
+ private toastService: ToastService,
) {}
get title() {
@@ -36,6 +38,10 @@ export class SecretHardDeleteDialogComponent {
const message =
this.data.secretIds.length === 1 ? "hardDeleteSuccessToast" : "hardDeletesSuccessToast";
this.dialogRef.close(this.data.secretIds);
- this.platformUtilsService.showToast("success", null, this.i18nService.t(message));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t(message),
+ });
};
}
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-restore.component.ts b/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-restore.component.ts
index 81fbeb1f182..eae6c7c9b9e 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-restore.component.ts
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/trash/dialog/secret-restore.component.ts
@@ -3,6 +3,7 @@ import { Component, Inject } from "@angular/core";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
+import { ToastService } from "@bitwarden/components";
import { SecretService } from "../../secrets/secret.service";
@@ -21,6 +22,7 @@ export class SecretRestoreDialogComponent {
private i18nService: I18nService,
private platformUtilsService: PlatformUtilsService,
@Inject(DIALOG_DATA) public data: SecretRestoreOperation,
+ private toastService: ToastService,
) {}
get title() {
@@ -35,6 +37,10 @@ export class SecretRestoreDialogComponent {
? "secretRestoredSuccessToast"
: "secretsRestoredSuccessToast";
this.dialogRef.close(this.data.secretIds);
- this.platformUtilsService.showToast("success", null, this.i18nService.t(message));
+ this.toastService.showToast({
+ variant: "success",
+ title: null,
+ message: this.i18nService.t(message),
+ });
};
}
From aa7c9685b6a0896a370b89535cefab21ca87b5a4 Mon Sep 17 00:00:00 2001
From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com>
Date: Fri, 23 Aug 2024 10:33:32 -0600
Subject: [PATCH 03/11] [deps] DevOps: Update chromaui/action action to v11
(#10595)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
---
.github/workflows/chromatic.yml | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/.github/workflows/chromatic.yml b/.github/workflows/chromatic.yml
index 9ae2db7244b..6a02c2d1245 100644
--- a/.github/workflows/chromatic.yml
+++ b/.github/workflows/chromatic.yml
@@ -57,7 +57,7 @@ jobs:
run: npm run build-storybook:ci
- name: Publish to Chromatic
- uses: chromaui/action@c9067691aca4a28d6fbb40d9eea6e144369fbcae # v10.9.5
+ uses: chromaui/action@b984808b772126a9f44b2b7737b131b68a2ede32 # v11.7.1
with:
token: ${{ secrets.GITHUB_TOKEN }}
projectToken: ${{ secrets.CHROMATIC_PROJECT_TOKEN }}
From c2829cd71b835f9be56e97e5ba8637c5f8490a9a Mon Sep 17 00:00:00 2001
From: Matt Gibson
Date: Fri, 23 Aug 2024 10:51:42 -0700
Subject: [PATCH 04/11] Remove password hint responses from API (#10523)
* Log reloading behavior
* Remove hints from responses.
changing password implies updating the hint, but no longer displays the old one. This is a security risk for shoulder surfing and breaks the escrow model we have where it is only shared via email when requested.
* Update change password hint label
---
apps/desktop/src/main/window.main.ts | 2 ++
apps/web/src/app/auth/settings/account/profile.component.ts | 5 +----
.../src/app/auth/settings/change-password.component.html | 2 +-
apps/web/src/app/auth/settings/change-password.component.ts | 6 ++++--
apps/web/src/locales/en/messages.json | 3 +++
.../src/auth/models/request/update-profile.request.ts | 4 +---
libs/common/src/models/response/profile.response.ts | 2 --
7 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/apps/desktop/src/main/window.main.ts b/apps/desktop/src/main/window.main.ts
index deb370201ff..029a0527c6e 100644
--- a/apps/desktop/src/main/window.main.ts
+++ b/apps/desktop/src/main/window.main.ts
@@ -51,6 +51,7 @@ export class WindowMain {
// Perform a hard reload of the render process by crashing it. This is suboptimal but ensures that all memory gets
// cleared, as the process itself will be completely garbage collected.
ipcMain.on("reload-process", async () => {
+ this.logService.info("Reloading render process");
// User might have changed theme, ensure the window is updated.
this.win.setBackgroundColor(await this.getBackgroundColor());
@@ -65,6 +66,7 @@ export class WindowMain {
// FIXME: Verify that this floating promise is intentional. If it is, add an explanatory comment and ensure there is proper error handling.
// eslint-disable-next-line @typescript-eslint/no-floating-promises
this.session.clearCache();
+ this.logService.info("Render process reloaded");
});
return new Promise((resolve, reject) => {
diff --git a/apps/web/src/app/auth/settings/account/profile.component.ts b/apps/web/src/app/auth/settings/account/profile.component.ts
index fa111c9fa6e..a960adfe5de 100644
--- a/apps/web/src/app/auth/settings/account/profile.component.ts
+++ b/apps/web/src/app/auth/settings/account/profile.component.ts
@@ -62,10 +62,7 @@ export class ProfileComponent implements OnInit, OnDestroy {
}
submit = async () => {
- const request = new UpdateProfileRequest(
- this.formGroup.get("name").value,
- this.profile.masterPasswordHint,
- );
+ const request = new UpdateProfileRequest(this.formGroup.get("name").value);
await this.apiService.putProfile(request);
this.platformUtilsService.showToast("success", null, this.i18nService.t("accountUpdated"));
};
diff --git a/apps/web/src/app/auth/settings/change-password.component.html b/apps/web/src/app/auth/settings/change-password.component.html
index 7c3c22b3d7e..b5c8677405f 100644
--- a/apps/web/src/app/auth/settings/change-password.component.html
+++ b/apps/web/src/app/auth/settings/change-password.component.html
@@ -111,7 +111,7 @@