1
0
mirror of https://github.com/bitwarden/browser synced 2026-02-07 04:03:29 +00:00

[PM-29621] Changed error message to indicate lack of permissions (#18528)

This commit is contained in:
Vijay Oommen
2026-02-06 12:36:44 -06:00
committed by GitHub
parent b6ff3a110e
commit cb2e5a04d0
4 changed files with 68 additions and 35 deletions

View File

@@ -10499,6 +10499,9 @@
"failedToSaveIntegration": {
"message": "Failed to save integration. Please try again later."
},
"mustBeOrganizationOwnerAdmin": {
"message": "You must be an Organization Owner or Admin to perform this action."
},
"mustBeOrgOwnerToPerformAction": {
"message": "You must be the organization owner to perform this action."
},

View File

@@ -18,6 +18,7 @@ import {
AllActivitiesService,
RiskInsightsDataService,
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { CipherId, OrganizationId } from "@bitwarden/common/types/guid";
import { SecurityTask, SecurityTaskStatus } from "@bitwarden/common/vault/tasks";
@@ -170,7 +171,16 @@ export class PasswordChangeMetricComponent implements OnInit {
variant: "success",
title: this.i18nService.t("success"),
});
} catch {
} catch (error) {
if (error instanceof ErrorResponse && error.statusCode === 404) {
this.toastService.showToast({
message: this.i18nService.t("mustBeOrganizationOwnerAdmin"),
variant: "error",
title: this.i18nService.t("error"),
});
return;
}
this.toastService.showToast({
message: this.i18nService.t("unexpectedError"),
variant: "error",

View File

@@ -10,13 +10,14 @@ import {
signal,
} from "@angular/core";
import { takeUntilDestroyed, toSignal } from "@angular/core/rxjs-interop";
import { from, switchMap, take } from "rxjs";
import { catchError, EMPTY, from, switchMap, take } from "rxjs";
import {
ApplicationHealthReportDetail,
RiskInsightsDataService,
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
import { getUniqueMembers } from "@bitwarden/bit-common/dirt/reports/risk-insights/helpers";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { CipherId, OrganizationId } from "@bitwarden/common/types/guid";
@@ -289,18 +290,18 @@ export class NewApplicationsDialogComponent {
),
);
}),
)
.subscribe({
next: () => {
this.toastService.showToast({
variant: "success",
title: this.i18nService.t("applicationReviewSaved"),
message: this.i18nService.t("newApplicationsReviewed"),
});
this.saving.set(false);
this.handleAssigningCompleted();
},
error: (error: unknown) => {
catchError((error: unknown) => {
if (error instanceof ErrorResponse && error.statusCode === 404) {
this.toastService.showToast({
message: this.i18nService.t("mustBeOrganizationOwnerAdmin"),
variant: "error",
title: this.i18nService.t("error"),
});
this.saving.set(false);
return EMPTY;
}
this.logService.error(
"[NewApplicationsDialog] Failed to save application review or assign tasks",
error,
@@ -311,7 +312,19 @@ export class NewApplicationsDialogComponent {
title: this.i18nService.t("errorSavingReviewStatus"),
message: this.i18nService.t("pleaseTryAgain"),
});
},
this.saving.set(false);
return EMPTY;
}),
)
.subscribe(() => {
this.toastService.showToast({
variant: "success",
title: this.i18nService.t("applicationReviewSaved"),
message: this.i18nService.t("newApplicationsReviewed"),
});
this.saving.set(false);
this.handleAssigningCompleted();
});
}

View File

@@ -1,10 +1,8 @@
// FIXME: Update this file to be type safe and remove this and next line
// @ts-strict-ignore
import { Component, DestroyRef, inject, OnInit, ChangeDetectionStrategy } from "@angular/core";
import { takeUntilDestroyed } from "@angular/core/rxjs-interop";
import { FormControl } from "@angular/forms";
import { ActivatedRoute, Router } from "@angular/router";
import { debounceTime, EMPTY, from, map, switchMap, take } from "rxjs";
import { catchError, debounceTime, EMPTY, from, map, switchMap, take } from "rxjs";
import { Security } from "@bitwarden/assets/svg";
import {
@@ -14,6 +12,7 @@ import {
} from "@bitwarden/bit-common/dirt/reports/risk-insights";
import { createNewSummaryData } from "@bitwarden/bit-common/dirt/reports/risk-insights/helpers";
import { OrganizationReportSummary } from "@bitwarden/bit-common/dirt/reports/risk-insights/models/report-models";
import { ErrorResponse } from "@bitwarden/common/models/response/error.response";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { OrganizationId } from "@bitwarden/common/types/guid";
import {
@@ -53,7 +52,7 @@ import { AccessIntelligenceSecurityTasksService } from "../shared/security-tasks
export class CriticalApplicationsComponent implements OnInit {
private destroyRef = inject(DestroyRef);
protected enableRequestPasswordChange = false;
protected organizationId: OrganizationId;
protected organizationId: OrganizationId = "" as OrganizationId;
noItemsIcon = Security;
protected dataSource = new TableDataSource<ApplicationTableDataSource>();
@@ -151,35 +150,43 @@ export class CriticalApplicationsComponent implements OnInit {
});
};
async requestPasswordChange() {
requestPasswordChange(): void {
this.dataService.criticalApplicationAtRiskCipherIds$
.pipe(
takeUntilDestroyed(this.destroyRef), // Satisfy eslint rule
take(1), // Handle unsubscribe for one off operation
switchMap((cipherIds) => {
return from(
switchMap((cipherIds) =>
from(
this.securityTasksService.requestPasswordChangeForCriticalApplications(
this.organizationId,
cipherIds,
),
);
}),
)
.subscribe({
next: () => {
this.toastService.showToast({
message: this.i18nService.t("notifiedMembers"),
variant: "success",
title: this.i18nService.t("success"),
});
},
error: () => {
),
),
catchError((error: unknown) => {
if (error instanceof ErrorResponse && error.statusCode === 404) {
this.toastService.showToast({
message: this.i18nService.t("mustBeOrganizationOwnerAdmin"),
variant: "error",
title: this.i18nService.t("error"),
});
return EMPTY;
}
this.toastService.showToast({
message: this.i18nService.t("unexpectedError"),
variant: "error",
title: this.i18nService.t("error"),
});
},
return EMPTY;
}),
)
.subscribe(() => {
this.toastService.showToast({
message: this.i18nService.t("notifiedMembers"),
variant: "success",
title: this.i18nService.t("success"),
});
});
}