1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-10 21:33:27 +00:00

[PM-18322] Fix: Allow organization admins to upload attachments for items without direct access (#14361)

* Wire organization ID into AttachmentsV2Component for org-based ciphers

* Enhance AttachmentsV2Component to accept organization ID for improved handling of org-based ciphers

* Integrate organization ID into VaultComponent for AttachmentsV2Component to enhance org-based cipher handling

* Add unit tests for CipherAttachmentsComponent to validate attachment saving behavior for admins

- Introduced mocks for ApiService and OrganizationService in the test setup.
- Updated tests to check `saveAttachmentWithServer` calls with the correct parameters, including an `isAdmin` flag for admin API usage.

* Fix unit tests for AttachmentsV2Component by adding mocks for ApiService and OrganizationService

* Fix AttachmentsV2Component tests
This commit is contained in:
Rui Tomé
2025-04-29 12:42:02 +01:00
committed by GitHub
parent 67b1158bf0
commit 9cd08e8a9f
10 changed files with 122 additions and 21 deletions

View File

@@ -5,6 +5,8 @@ import { ActivatedRoute, Router } from "@angular/router";
import { mock } from "jest-mock-extended";
import { BehaviorSubject } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -77,6 +79,8 @@ describe("AttachmentsV2Component", () => {
provide: AccountService,
useValue: accountService,
},
{ provide: ApiService, useValue: mock<ApiService>() },
{ provide: OrganizationService, useValue: mock<OrganizationService>() },
],
})
.overrideComponent(AttachmentsV2Component, {

View File

@@ -809,6 +809,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const dialogRef = AttachmentsV2Component.open(this.dialogService, {
cipherId: cipher.id as CipherId,
organizationId: cipher.organizationId as OrganizationId,
});
const result = await firstValueFrom(dialogRef.closed);

View File

@@ -20,7 +20,7 @@ import { ConfigService } from "@bitwarden/common/platform/abstractions/config/co
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
import { CipherId, CollectionId } from "@bitwarden/common/types/guid";
import { CipherId, CollectionId, OrganizationId } from "@bitwarden/common/types/guid";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
import { PremiumUpgradePromptService } from "@bitwarden/common/vault/abstractions/premium-upgrade-prompt.service";
import { ViewPasswordHistoryService } from "@bitwarden/common/vault/abstractions/view-password-history.service";
@@ -441,14 +441,15 @@ export class VaultItemDialogComponent implements OnInit, OnDestroy {
return;
}
const dialogRef = this.dialogService.open<AttachmentDialogCloseResult, { cipherId: CipherId }>(
AttachmentsV2Component,
{
data: {
cipherId: this.formConfig.originalCipher?.id as CipherId,
},
const dialogRef = this.dialogService.open<
AttachmentDialogCloseResult,
{ cipherId: CipherId; organizationId?: OrganizationId }
>(AttachmentsV2Component, {
data: {
cipherId: this.formConfig.originalCipher?.id as CipherId,
organizationId: this.formConfig.originalCipher?.organizationId as OrganizationId,
},
);
});
const result = await firstValueFrom(dialogRef.closed);

View File

@@ -8,7 +8,7 @@ import { switchMap } from "rxjs";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { CipherId } from "@bitwarden/common/types/guid";
import { CipherId, OrganizationId } from "@bitwarden/common/types/guid";
import { CipherType } from "@bitwarden/common/vault/enums/cipher-type";
import { CipherView } from "@bitwarden/common/vault/models/view/cipher.view";
import {
@@ -155,14 +155,15 @@ export class AddEditComponentV2 implements OnInit {
* Opens the attachments dialog.
*/
async openAttachmentsDialog() {
this.dialogService.open<AttachmentsV2Component, { cipherId: CipherId }>(
this.dialogService.open<
AttachmentsV2Component,
{
data: {
cipherId: this.config.originalCipher?.id as CipherId,
},
{ cipherId: CipherId; organizationId?: OrganizationId }
>(AttachmentsV2Component, {
data: {
cipherId: this.config.originalCipher?.id as CipherId,
organizationId: this.config.originalCipher?.organizationId as OrganizationId,
},
);
});
}
/**

View File

@@ -652,6 +652,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const dialogRef = AttachmentsV2Component.open(this.dialogService, {
cipherId: cipher.id as CipherId,
organizationId: cipher.organizationId as OrganizationId,
});
const result: AttachmentDialogCloseResult = await lastValueFrom(dialogRef.closed);