mirror of
https://github.com/bitwarden/clients.git
synced 2026-07-07 21:10:55 +08:00
[PM-33928] Fix: Can view MyItems Passwords in Org Vault Health Reports (#19874)
* fix(bug): Admin/Owner viewing and editing ciphers from within health reports * Change check for unassigned ciphers to include default collection check * Remove unnecessary typecasting
This commit is contained in:
parent
3751227752
commit
4c3cf00a5a
@ -2,6 +2,7 @@ import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { firstValueFrom, takeUntil, tap } from "rxjs";
|
||||
|
||||
import { CollectionService } from "@bitwarden/admin-console/common";
|
||||
import { AuditService } from "@bitwarden/common/abstractions/audit.service";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
@ -10,8 +11,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { getById } from "@bitwarden/common/platform/misc";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CipherViewLikeUtils } from "@bitwarden/common/vault/utils/cipher-view-like-utils";
|
||||
import { BerryComponent, ChipFilterComponent, DialogService } from "@bitwarden/components";
|
||||
import {
|
||||
PasswordRepromptService,
|
||||
@ -54,7 +55,8 @@ export class ExposedPasswordsReportComponent
|
||||
extends BaseExposedPasswordsReportComponent
|
||||
implements OnInit
|
||||
{
|
||||
private manageableCiphers: Cipher[] = [];
|
||||
private manageableCipherIds = new Set<string>();
|
||||
private sharedCollectionIds = new Set<string>();
|
||||
|
||||
constructor(
|
||||
cipherService: CipherService,
|
||||
@ -68,6 +70,7 @@ export class ExposedPasswordsReportComponent
|
||||
syncService: SyncService,
|
||||
cipherFormService: CipherFormConfigService,
|
||||
adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService,
|
||||
private collectionService: CollectionService,
|
||||
) {
|
||||
super(
|
||||
cipherService,
|
||||
@ -92,7 +95,17 @@ export class ExposedPasswordsReportComponent
|
||||
this.organization = await firstValueFrom(
|
||||
this.organizationService.organizations$(userId).pipe(getById(params.organizationId)),
|
||||
);
|
||||
this.manageableCiphers = await this.cipherService.getAll(userId);
|
||||
const manageableCiphers = await this.cipherService.getAll(userId);
|
||||
this.manageableCipherIds = new Set(manageableCiphers.map((c) => c.id));
|
||||
const collections = await firstValueFrom(
|
||||
this.collectionService.decryptedCollections$(userId),
|
||||
);
|
||||
this.sharedCollectionIds = new Set(
|
||||
collections
|
||||
.filter((c) => !c.isDefaultCollection && c.organizationId === this.organization?.id)
|
||||
.map((c) => c.id as string),
|
||||
);
|
||||
await super.ngOnInit();
|
||||
}),
|
||||
takeUntil(this.destroyed$),
|
||||
)
|
||||
@ -107,12 +120,15 @@ export class ExposedPasswordsReportComponent
|
||||
}
|
||||
|
||||
canManageCipher(c: CipherView): boolean {
|
||||
if (c.collectionIds.length === 0) {
|
||||
return true;
|
||||
if (
|
||||
CipherViewLikeUtils.isUnassigned(c) ||
|
||||
!c.collectionIds?.some((id) => this.sharedCollectionIds.has(id))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (this.organization?.allowAdminAccessToAllCollectionItems) {
|
||||
return true;
|
||||
}
|
||||
return this.manageableCiphers.some((x) => x.id === c.id);
|
||||
return this.manageableCipherIds.has(c.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import { ChangeDetectorRef, Component, OnInit, ChangeDetectionStrategy } from "@
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { firstValueFrom, takeUntil, tap } from "rxjs";
|
||||
|
||||
import { CollectionService } from "@bitwarden/admin-console/common";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
@ -12,8 +13,8 @@ import { LogService } from "@bitwarden/common/platform/abstractions/log.service"
|
||||
import { getById } from "@bitwarden/common/platform/misc";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CipherViewLikeUtils } from "@bitwarden/common/vault/utils/cipher-view-like-utils";
|
||||
import {
|
||||
BerryComponent,
|
||||
ChipActionComponent,
|
||||
@ -61,8 +62,8 @@ export class InactiveTwoFactorReportComponent
|
||||
extends BaseInactiveTwoFactorReportComponent
|
||||
implements OnInit
|
||||
{
|
||||
// Contains a list of ciphers, the user running the report, can manage
|
||||
private manageableCiphers: Cipher[] = [];
|
||||
private manageableCipherIds = new Set<string>();
|
||||
private sharedCollectionIds = new Set<string>();
|
||||
|
||||
constructor(
|
||||
cipherService: CipherService,
|
||||
@ -77,6 +78,7 @@ export class InactiveTwoFactorReportComponent
|
||||
cipherFormConfigService: CipherFormConfigService,
|
||||
adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService,
|
||||
protected changeDetectorRef: ChangeDetectorRef,
|
||||
private collectionService: CollectionService,
|
||||
) {
|
||||
super(
|
||||
cipherService,
|
||||
@ -103,7 +105,16 @@ export class InactiveTwoFactorReportComponent
|
||||
this.organization = await firstValueFrom(
|
||||
this.organizationService.organizations$(userId).pipe(getById(params.organizationId)),
|
||||
);
|
||||
this.manageableCiphers = await this.cipherService.getAll(userId);
|
||||
const manageableCiphers = await this.cipherService.getAll(userId);
|
||||
this.manageableCipherIds = new Set(manageableCiphers.map((c) => c.id));
|
||||
const collections = await firstValueFrom(
|
||||
this.collectionService.decryptedCollections$(userId),
|
||||
);
|
||||
this.sharedCollectionIds = new Set(
|
||||
collections
|
||||
.filter((c) => !c.isDefaultCollection && c.organizationId === this.organization?.id)
|
||||
.map((c) => c.id as string),
|
||||
);
|
||||
await super.ngOnInit();
|
||||
this.changeDetectorRef.markForCheck();
|
||||
}),
|
||||
@ -120,12 +131,15 @@ export class InactiveTwoFactorReportComponent
|
||||
}
|
||||
|
||||
protected canManageCipher(c: CipherView): boolean {
|
||||
if (c.collectionIds.length === 0) {
|
||||
return true;
|
||||
if (
|
||||
CipherViewLikeUtils.isUnassigned(c) ||
|
||||
!c.collectionIds?.some((id) => this.sharedCollectionIds.has(id))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (this.organization?.allowAdminAccessToAllCollectionItems) {
|
||||
return true;
|
||||
}
|
||||
return this.manageableCiphers.some((x) => x.id === c.id);
|
||||
return this.manageableCipherIds.has(c.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { firstValueFrom, takeUntil, tap } from "rxjs";
|
||||
|
||||
import { CollectionService } from "@bitwarden/admin-console/common";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
@ -9,8 +10,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { getById } from "@bitwarden/common/platform/misc";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CipherViewLikeUtils } from "@bitwarden/common/vault/utils/cipher-view-like-utils";
|
||||
import { BerryComponent, ChipFilterComponent, DialogService } from "@bitwarden/components";
|
||||
import {
|
||||
CipherFormConfigService,
|
||||
@ -53,7 +54,8 @@ export class ReusedPasswordsReportComponent
|
||||
extends BaseReusedPasswordsReportComponent
|
||||
implements OnInit
|
||||
{
|
||||
manageableCiphers: Cipher[] = [];
|
||||
private manageableCipherIds = new Set<string>();
|
||||
private sharedCollectionIds = new Set<string>();
|
||||
|
||||
constructor(
|
||||
cipherService: CipherService,
|
||||
@ -66,6 +68,7 @@ export class ReusedPasswordsReportComponent
|
||||
syncService: SyncService,
|
||||
cipherFormConfigService: CipherFormConfigService,
|
||||
adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService,
|
||||
private collectionService: CollectionService,
|
||||
) {
|
||||
super(
|
||||
cipherService,
|
||||
@ -90,7 +93,16 @@ export class ReusedPasswordsReportComponent
|
||||
this.organization = await firstValueFrom(
|
||||
this.organizationService.organizations$(userId).pipe(getById(params.organizationId)),
|
||||
);
|
||||
this.manageableCiphers = await this.cipherService.getAll(userId);
|
||||
const manageableCiphers = await this.cipherService.getAll(userId);
|
||||
this.manageableCipherIds = new Set(manageableCiphers.map((c) => c.id));
|
||||
const collections = await firstValueFrom(
|
||||
this.collectionService.decryptedCollections$(userId),
|
||||
);
|
||||
this.sharedCollectionIds = new Set(
|
||||
collections
|
||||
.filter((c) => !c.isDefaultCollection && c.organizationId === this.organization?.id)
|
||||
.map((c) => c.id as string),
|
||||
);
|
||||
await super.ngOnInit();
|
||||
}),
|
||||
takeUntil(this.destroyed$),
|
||||
@ -106,12 +118,15 @@ export class ReusedPasswordsReportComponent
|
||||
}
|
||||
|
||||
canManageCipher(c: CipherView): boolean {
|
||||
if (c.collectionIds.length === 0) {
|
||||
return true;
|
||||
if (
|
||||
CipherViewLikeUtils.isUnassigned(c) ||
|
||||
!c.collectionIds?.some((id) => this.sharedCollectionIds.has(id))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (this.organization?.allowAdminAccessToAllCollectionItems) {
|
||||
return true;
|
||||
}
|
||||
return this.manageableCiphers.some((x) => x.id === c.id);
|
||||
return this.manageableCipherIds.has(c.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -10,8 +10,8 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
|
||||
import { getById } from "@bitwarden/common/platform/misc";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CipherViewLikeUtils } from "@bitwarden/common/vault/utils/cipher-view-like-utils";
|
||||
import { BerryComponent, ChipFilterComponent, DialogService } from "@bitwarden/components";
|
||||
import {
|
||||
CipherFormConfigService,
|
||||
@ -54,8 +54,8 @@ export class UnsecuredWebsitesReportComponent
|
||||
extends BaseUnsecuredWebsitesReportComponent
|
||||
implements OnInit
|
||||
{
|
||||
// Contains a list of ciphers, the user running the report, can manage
|
||||
private manageableCiphers: Cipher[] = [];
|
||||
private manageableCipherIds = new Set<string>();
|
||||
private sharedCollectionIds = new Set<string>();
|
||||
|
||||
constructor(
|
||||
cipherService: CipherService,
|
||||
@ -93,7 +93,16 @@ export class UnsecuredWebsitesReportComponent
|
||||
this.organization = await firstValueFrom(
|
||||
this.organizationService.organizations$(userId).pipe(getById(params.organizationId)),
|
||||
);
|
||||
this.manageableCiphers = await this.cipherService.getAll(userId);
|
||||
const manageableCiphers = await this.cipherService.getAll(userId);
|
||||
this.manageableCipherIds = new Set(manageableCiphers.map((c) => c.id));
|
||||
const collections = await firstValueFrom(
|
||||
this.collectionService.decryptedCollections$(userId),
|
||||
);
|
||||
this.sharedCollectionIds = new Set(
|
||||
collections
|
||||
.filter((c) => !c.isDefaultCollection && c.organizationId === this.organization?.id)
|
||||
.map((c) => c.id as string),
|
||||
);
|
||||
await super.ngOnInit();
|
||||
}),
|
||||
takeUntil(this.destroyed$),
|
||||
@ -109,12 +118,15 @@ export class UnsecuredWebsitesReportComponent
|
||||
}
|
||||
|
||||
protected canManageCipher(c: CipherView): boolean {
|
||||
if (c.collectionIds.length === 0) {
|
||||
return true;
|
||||
if (
|
||||
CipherViewLikeUtils.isUnassigned(c) ||
|
||||
!c.collectionIds?.some((id) => this.sharedCollectionIds.has(id))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (this.organization?.allowAdminAccessToAllCollectionItems) {
|
||||
return true;
|
||||
}
|
||||
return this.manageableCiphers.some((x) => x.id === c.id);
|
||||
return this.manageableCipherIds.has(c.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,6 +2,7 @@ import { Component, OnInit } from "@angular/core";
|
||||
import { ActivatedRoute } from "@angular/router";
|
||||
import { firstValueFrom, takeUntil, tap } from "rxjs";
|
||||
|
||||
import { CollectionService } from "@bitwarden/admin-console/common";
|
||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
|
||||
import { getUserId } from "@bitwarden/common/auth/services/account.service";
|
||||
@ -10,8 +11,8 @@ import { getById } from "@bitwarden/common/platform/misc";
|
||||
import { PasswordStrengthServiceAbstraction } from "@bitwarden/common/tools/password-strength";
|
||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||
import { Cipher } from "@bitwarden/common/vault/models/domain/cipher";
|
||||
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
|
||||
import { CipherViewLikeUtils } from "@bitwarden/common/vault/utils/cipher-view-like-utils";
|
||||
import { BerryComponent, ChipFilterComponent, DialogService } from "@bitwarden/components";
|
||||
import {
|
||||
CipherFormConfigService,
|
||||
@ -54,7 +55,8 @@ export class WeakPasswordsReportComponent
|
||||
extends BaseWeakPasswordsReportComponent
|
||||
implements OnInit
|
||||
{
|
||||
private manageableCiphers: Cipher[] = [];
|
||||
private manageableCipherIds = new Set<string>();
|
||||
private sharedCollectionIds = new Set<string>();
|
||||
|
||||
constructor(
|
||||
cipherService: CipherService,
|
||||
@ -68,6 +70,7 @@ export class WeakPasswordsReportComponent
|
||||
cipherFormConfigService: CipherFormConfigService,
|
||||
protected accountService: AccountService,
|
||||
adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService,
|
||||
private collectionService: CollectionService,
|
||||
) {
|
||||
super(
|
||||
cipherService,
|
||||
@ -92,7 +95,16 @@ export class WeakPasswordsReportComponent
|
||||
this.organization = await firstValueFrom(
|
||||
this.organizationService.organizations$(userId).pipe(getById(params.organizationId)),
|
||||
);
|
||||
this.manageableCiphers = await this.cipherService.getAll(userId);
|
||||
const manageableCiphers = await this.cipherService.getAll(userId);
|
||||
this.manageableCipherIds = new Set(manageableCiphers.map((c) => c.id));
|
||||
const collections = await firstValueFrom(
|
||||
this.collectionService.decryptedCollections$(userId),
|
||||
);
|
||||
this.sharedCollectionIds = new Set(
|
||||
collections
|
||||
.filter((c) => !c.isDefaultCollection && c.organizationId === this.organization?.id)
|
||||
.map((c) => c.id as string),
|
||||
);
|
||||
await super.ngOnInit();
|
||||
}),
|
||||
takeUntil(this.destroyed$),
|
||||
@ -108,12 +120,15 @@ export class WeakPasswordsReportComponent
|
||||
}
|
||||
|
||||
canManageCipher(c: CipherView): boolean {
|
||||
if (c.collectionIds.length === 0) {
|
||||
return true;
|
||||
if (
|
||||
CipherViewLikeUtils.isUnassigned(c) ||
|
||||
!c.collectionIds?.some((id) => this.sharedCollectionIds.has(id))
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
if (this.organization?.allowAdminAccessToAllCollectionItems) {
|
||||
return true;
|
||||
}
|
||||
return this.manageableCiphers.some((x) => x.id === c.id);
|
||||
return this.manageableCipherIds.has(c.id);
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ export class UnsecuredWebsitesReportComponent extends CipherReportComponent impl
|
||||
passwordRepromptService: PasswordRepromptService,
|
||||
i18nService: I18nService,
|
||||
syncService: SyncService,
|
||||
private collectionService: CollectionService,
|
||||
protected collectionService: CollectionService,
|
||||
cipherFormConfigService: CipherFormConfigService,
|
||||
adminConsoleCipherFormConfigService: AdminConsoleCipherFormConfigService,
|
||||
) {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user