From 59d1fe647d843ad6c36c54796ffdd993d6cd6422 Mon Sep 17 00:00:00 2001 From: Rui Tome Date: Mon, 4 Dec 2023 20:21:47 +0000 Subject: [PATCH] [AC-1139] Fix canDelete logic in collection-dialog.component.ts and bulk-delete-dialog.component.ts --- .../collection-dialog.component.ts | 46 +++++----- .../bulk-delete-dialog.component.ts | 30 +++---- .../vault/individual-vault/vault.component.ts | 75 ++++++++-------- .../app/vault/org-vault/vault.component.ts | 89 +++++++++---------- 4 files changed, 112 insertions(+), 128 deletions(-) diff --git a/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts index 6e36fc975e5..f734fe05857 100644 --- a/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts +++ b/apps/web/src/app/vault/components/collection-dialog/collection-dialog.component.ts @@ -72,7 +72,7 @@ export enum CollectionDialogAction { export class CollectionDialogComponent implements OnInit, OnDestroy { protected flexibleCollectionsEnabled$ = this.configService.getFeatureFlag$( FeatureFlag.FlexibleCollections, - false + false, ); private destroy$ = new Subject(); @@ -107,7 +107,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { private organizationUserService: OrganizationUserService, private dialogService: DialogService, private changeDetectorRef: ChangeDetectorRef, - private configService: ConfigServiceAbstraction + private configService: ConfigServiceAbstraction, ) { this.tabIndex = params.initialTab ?? CollectionDialogTabType.Info; } @@ -123,8 +123,8 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { map((orgs) => orgs .filter((o) => o.canCreateNewCollections && !o.isProviderUser) - .sort(Utils.getSortFunction(this.i18nService, "name")) - ) + .sort(Utils.getSortFunction(this.i18nService, "name")), + ), ); // patchValue will trigger a call to loadOrg() in this case, so no need to call it again here this.formGroup.patchValue({ selectedOrg: this.params.organizationId }); @@ -141,7 +141,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { async loadOrg(orgId: string, collectionIds: string[]) { const organization$ = of(this.organizationService.get(orgId)).pipe( - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const groups$ = organization$.pipe( switchMap((organization) => { @@ -150,7 +150,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { } return this.groupService.getAll(orgId); - }) + }), ); combineLatest({ organization: organization$, @@ -168,7 +168,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { this.organization = organization; this.accessItems = [].concat( groups.map(mapGroupToAccessItemView), - users.data.map(mapUserToAccessItemView) + users.data.map(mapUserToAccessItemView), ); // Force change detection to update the access selector's items @@ -201,9 +201,8 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { } else { this.nestOptions = collections; const parent = collections.find((c) => c.id === this.params.parentCollectionId); - const currentOrgUserId = users.data.find( - (u) => u.userId === this.organization?.userId - )?.id; + const currentOrgUserId = users.data.find((u) => u.userId === this.organization?.userId) + ?.id; const initialSelection: AccessItemValue[] = currentOrgUserId !== undefined ? [ @@ -224,7 +223,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { } this.loading = false; - } + }, ); } @@ -250,13 +249,13 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", null, - this.i18nService.t("fieldOnTabRequiresAttention", this.i18nService.t("collectionInfo")) + this.i18nService.t("fieldOnTabRequiresAttention", this.i18nService.t("collectionInfo")), ); } else if (this.tabIndex === CollectionDialogTabType.Info && accessTabError) { this.platformUtilsService.showToast( "error", null, - this.i18nService.t("fieldOnTabRequiresAttention", this.i18nService.t("access")) + this.i18nService.t("fieldOnTabRequiresAttention", this.i18nService.t("access")), ); } return; @@ -287,8 +286,8 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { null, this.i18nService.t( this.editMode ? "editedCollectionId" : "createdCollectionId", - collectionView.name - ) + collectionView.name, + ), ); this.close(CollectionDialogAction.Saved, savedCollection); @@ -310,18 +309,17 @@ export class CollectionDialogComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "success", null, - this.i18nService.t("deletedCollectionId", this.collection?.name) + this.i18nService.t("deletedCollectionId", this.collection?.name), ); this.close(CollectionDialogAction.Deleted, this.collection); }; protected canDelete$ = this.flexibleCollectionsEnabled$.pipe( - switchMap(async (flexibleCollectionsEnabled) => { - return ( - this.editMode && this.collection.canDelete(this.organization, flexibleCollectionsEnabled) - ); - }) + map( + (flexibleCollectionsEnabled) => + this.editMode && this.collection.canDelete(this.organization, flexibleCollectionsEnabled), + ), ); ngOnDestroy(): void { @@ -356,7 +354,7 @@ function mapToAccessSelections(collectionDetails: CollectionAdminView): AccessIt id: selection.id, type: AccessItemType.Member, permission: convertToPermission(selection), - })) + })), ); } @@ -377,10 +375,10 @@ function validateCanManagePermission(control: AbstractControl) { */ export function openCollectionDialog( dialogService: DialogService, - config: DialogConfig + config: DialogConfig, ) { return dialogService.open( CollectionDialogComponent, - config + config, ); } diff --git a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts index 257d12f5709..209a4d051b8 100644 --- a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts +++ b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts @@ -34,11 +34,11 @@ export enum BulkDeleteDialogResult { */ export const openBulkDeleteDialog = ( dialogService: DialogService, - config: DialogConfig + config: DialogConfig, ) => { return dialogService.open( BulkDeleteDialogComponent, - config + config, ); }; @@ -61,7 +61,7 @@ export class BulkDeleteDialogComponent { private i18nService: I18nService, private apiService: ApiService, private collectionService: CollectionService, - private configService: ConfigServiceAbstraction + private configService: ConfigServiceAbstraction, ) { this.cipherIds = params.cipherIds ?? []; this.collectionIds = params.collectionIds ?? []; @@ -95,7 +95,7 @@ export class BulkDeleteDialogComponent { this.platformUtilsService.showToast( "success", null, - this.i18nService.t(this.permanent ? "permanentlyDeletedItems" : "deletedItems") + this.i18nService.t(this.permanent ? "permanentlyDeletedItems" : "deletedItems"), ); } if (this.collectionIds.length) { @@ -103,7 +103,7 @@ export class BulkDeleteDialogComponent { this.platformUtilsService.showToast( "success", null, - this.i18nService.t("deletedCollections") + this.i18nService.t("deletedCollections"), ); } this.close(BulkDeleteDialogResult.Deleted); @@ -130,20 +130,17 @@ export class BulkDeleteDialogComponent { private async deleteCollections(): Promise { const flexibleCollectionsEnabled = await this.configService.getFeatureFlag( FeatureFlag.FlexibleCollections, - false + false, ); // From org vault if (this.organization) { if ( - (flexibleCollectionsEnabled - ? this.collections.some((c) => !c.canDelete) - : !this.organization.canDeleteAssignedCollections) && - !this.organization.canDeleteAnyCollection + this.collections.some((c) => !c.canDelete(this.organization, flexibleCollectionsEnabled)) ) { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("missingPermissions") + this.i18nService.t("missingPermissions"), ); return; } @@ -152,16 +149,11 @@ export class BulkDeleteDialogComponent { } else if (this.organizations && this.collections) { const deletePromises: Promise[] = []; for (const organization of this.organizations) { - if ( - (flexibleCollectionsEnabled - ? this.collections.some((c) => !c.canDelete) - : !this.organization.canDeleteAssignedCollections) && - !organization.canDeleteAnyCollection - ) { + if (this.collections.some((c) => !c.canDelete(organization, flexibleCollectionsEnabled))) { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("missingPermissions") + this.i18nService.t("missingPermissions"), ); return; } @@ -169,7 +161,7 @@ export class BulkDeleteDialogComponent { .filter((o) => o.organizationId === organization.id) .map((c) => c.id); deletePromises.push( - this.apiService.deleteManyCollections(this.organization.id, orgCollections) + this.apiService.deleteManyCollections(this.organization.id, orgCollections), ); } return await Promise.all(deletePromises); diff --git a/apps/web/src/app/vault/individual-vault/vault.component.ts b/apps/web/src/app/vault/individual-vault/vault.component.ts index 8d2a6806a94..ab3425d1556 100644 --- a/apps/web/src/app/vault/individual-vault/vault.component.ts +++ b/apps/web/src/app/vault/individual-vault/vault.component.ts @@ -147,7 +147,7 @@ export class VaultComponent implements OnInit, OnDestroy { protected currentSearchText$: Observable; protected showBulkCollectionAccess$ = this.configService.getFeatureFlag$( FeatureFlag.BulkCollectionAccess, - false + false, ); private searchText$ = new Subject(); @@ -183,7 +183,7 @@ export class VaultComponent implements OnInit, OnDestroy { private searchPipe: SearchPipe, private configService: ConfigServiceAbstraction, private apiService: ApiService, - private userVerificationService: UserVerificationService + private userVerificationService: UserVerificationService, ) {} async ngOnInit() { @@ -191,7 +191,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.trashCleanupWarning = this.i18nService.t( this.platformUtilsService.isSelfHost() ? "trashCleanupWarningSelfHosted" - : "trashCleanupWarning" + : "trashCleanupWarning", ); const firstSetup$ = this.route.queryParams.pipe( @@ -219,7 +219,7 @@ export class VaultComponent implements OnInit, OnDestroy { await this.editCipher(cipherView); } }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => { @@ -243,11 +243,11 @@ export class VaultComponent implements OnInit, OnDestroy { const filter$ = this.routedVaultFilterService.filter$; const canAccessPremium$ = Utils.asyncToObservable(() => - this.stateService.getCanAccessPremium() + this.stateService.getCanAccessPremium(), ).pipe(shareReplay({ refCount: true, bufferSize: 1 })); const allCollections$ = Utils.asyncToObservable(() => this.collectionService.getAllDecrypted()); const nestedCollections$ = allCollections$.pipe( - map((collections) => getNestedCollectionTree(collections)) + map((collections) => getNestedCollectionTree(collections)), ); this.searchText$ @@ -257,7 +257,7 @@ export class VaultComponent implements OnInit, OnDestroy { queryParams: { search: Utils.isNullOrEmpty(searchText) ? null : searchText }, queryParamsHandling: "merge", replaceUrl: true, - }) + }), ); this.currentSearchText$ = this.route.queryParams.pipe(map((queryParams) => queryParams.search)); @@ -277,7 +277,7 @@ export class VaultComponent implements OnInit, OnDestroy { return ciphers.filter(filterFunction); }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const collections$ = combineLatest([nestedCollections$, filter$, this.currentSearchText$]).pipe( @@ -297,7 +297,7 @@ export class VaultComponent implements OnInit, OnDestroy { } else { const selectedCollection = ServiceUtils.getTreeNodeObjectFromList( collections, - filter.collectionId + filter.collectionId, ); collectionsToReturn = selectedCollection?.children.map((c) => c.node) ?? []; } @@ -307,13 +307,13 @@ export class VaultComponent implements OnInit, OnDestroy { collectionsToReturn, searchText, (collection) => collection.name, - (collection) => collection.id + (collection) => collection.id, ); } return collectionsToReturn; }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const selectedCollection$ = combineLatest([nestedCollections$, filter$]).pipe( @@ -329,7 +329,7 @@ export class VaultComponent implements OnInit, OnDestroy { return ServiceUtils.getTreeNodeObjectFromList(collections, filter.collectionId); }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); firstSetup$ @@ -344,7 +344,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("unknownCipher") + this.i18nService.t("unknownCipher"), ); this.router.navigate([], { queryParams: { itemId: null, cipherId: null }, @@ -353,7 +353,7 @@ export class VaultComponent implements OnInit, OnDestroy { } } }), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe(); @@ -370,9 +370,9 @@ export class VaultComponent implements OnInit, OnDestroy { ciphers$, collections$, selectedCollection$, - ]) + ]), ), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe( ([ @@ -393,7 +393,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.selectedCollection = selectedCollection; this.canCreateCollections = allOrganizations?.some( - (o) => o.canCreateNewCollections && !o.isProviderUser + (o) => o.canCreateNewCollections && !o.isProviderUser, ); this.showBulkMove = @@ -407,7 +407,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.performingInitialLoad = false; this.refreshing = false; - } + }, ); } @@ -534,7 +534,7 @@ export class VaultComponent implements OnInit, OnDestroy { comp.onReuploadedAttachment .pipe(takeUntil(this.destroy$)) .subscribe(() => (madeAttachmentChanges = true)); - } + }, ); modal.onClosed.pipe(takeUntil(this.destroy$)).subscribe(() => { @@ -559,7 +559,7 @@ export class VaultComponent implements OnInit, OnDestroy { modal.close(); this.refresh(); }); - } + }, ); } @@ -573,7 +573,7 @@ export class VaultComponent implements OnInit, OnDestroy { modal.close(); this.refresh(); }); - } + }, ); } @@ -589,7 +589,7 @@ export class VaultComponent implements OnInit, OnDestroy { const selectedColId = this.activeFilter.collectionId; if (selectedColId !== "AllCollections") { component.organizationId = component.collections.find( - (collection) => collection.id === selectedColId + (collection) => collection.id === selectedColId, )?.organizationId; component.collectionIds = [selectedColId]; } @@ -635,7 +635,7 @@ export class VaultComponent implements OnInit, OnDestroy { modal.close(); this.refresh(); }); - } + }, ); modal.onClosedPromise().then(() => { @@ -690,16 +690,13 @@ export class VaultComponent implements OnInit, OnDestroy { const organization = this.organizationService.get(collection.organizationId); const flexibleCollectionsEnabled = await this.configService.getFeatureFlag( FeatureFlag.FlexibleCollections, - false + false, ); - if ( - (flexibleCollectionsEnabled || !organization.canDeleteAssignedCollections) && - !organization.canDeleteAnyCollection - ) { + if (collection.canDelete(organization, flexibleCollectionsEnabled)) { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("missingPermissions") + this.i18nService.t("missingPermissions"), ); return; } @@ -717,7 +714,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "success", null, - this.i18nService.t("deletedCollectionId", collection.name) + this.i18nService.t("deletedCollectionId", collection.name), ); // Navigate away if we deleted the collection we were viewing if (this.selectedCollection?.node.id === collection.id) { @@ -778,7 +775,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("nothingSelected") + this.i18nService.t("nothingSelected"), ); return; } @@ -801,8 +798,8 @@ export class VaultComponent implements OnInit, OnDestroy { .map((i) => i.collection.organizationId); const orgs = await firstValueFrom( this.organizationService.organizations$.pipe( - map((orgs) => orgs.filter((o) => orgIds.includes(o.id))) - ) + map((orgs) => orgs.filter((o) => orgIds.includes(o.id))), + ), ); await this.bulkDelete(ciphers, collections, orgs); } @@ -830,7 +827,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "success", null, - this.i18nService.t(permanent ? "permanentlyDeletedItem" : "deletedItem") + this.i18nService.t(permanent ? "permanentlyDeletedItem" : "deletedItem"), ); this.refresh(); } catch (e) { @@ -841,7 +838,7 @@ export class VaultComponent implements OnInit, OnDestroy { async bulkDelete( ciphers: CipherView[], collections: CollectionView[], - organizations: Organization[] + organizations: Organization[], ) { if (!(await this.repromptCipher(ciphers))) { return; @@ -851,7 +848,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("nothingSelected") + this.i18nService.t("nothingSelected"), ); return; } @@ -881,7 +878,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("nothingSelected") + this.i18nService.t("nothingSelected"), ); return; } @@ -933,7 +930,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "info", null, - this.i18nService.t("valueCopied", this.i18nService.t(typeI18nKey)) + this.i18nService.t("valueCopied", this.i18nService.t(typeI18nKey)), ); if (field === "password") { @@ -952,7 +949,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("nothingSelected") + this.i18nService.t("nothingSelected"), ); return; } diff --git a/apps/web/src/app/vault/org-vault/vault.component.ts b/apps/web/src/app/vault/org-vault/vault.component.ts index 007b5d0b9a2..e6d6c12ac94 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -130,7 +130,7 @@ export class VaultComponent implements OnInit, OnDestroy { protected currentSearchText$: Observable; protected showBulkEditCollectionAccess$ = this.configService.getFeatureFlag$( FeatureFlag.BulkCollectionAccess, - false + false, ); protected flexibleCollectionsEnabled: boolean; @@ -164,27 +164,27 @@ export class VaultComponent implements OnInit, OnDestroy { private eventCollectionService: EventCollectionService, private totpService: TotpService, private apiService: ApiService, - protected configService: ConfigServiceAbstraction + protected configService: ConfigServiceAbstraction, ) {} async ngOnInit() { this.trashCleanupWarning = this.i18nService.t( this.platformUtilsService.isSelfHost() ? "trashCleanupWarningSelfHosted" - : "trashCleanupWarning" + : "trashCleanupWarning", ); const filter$ = this.routedVaultFilterService.filter$; const organizationId$ = filter$.pipe( map((filter) => filter.organizationId), filter((filter) => filter !== undefined), - distinctUntilChanged() + distinctUntilChanged(), ); const organization$ = organizationId$.pipe( switchMap((organizationId) => this.organizationService.get$(organizationId)), takeUntil(this.destroy$), - shareReplay({ refCount: false, bufferSize: 1 }) + shareReplay({ refCount: false, bufferSize: 1 }), ); const firstSetup$ = combineLatest([organization$, this.route.queryParams]).pipe( @@ -198,7 +198,7 @@ export class VaultComponent implements OnInit, OnDestroy { return undefined; }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); this.broadcasterService.subscribe(BroadcasterSubscriptionId, (message: any) => { @@ -227,14 +227,14 @@ export class VaultComponent implements OnInit, OnDestroy { queryParams: { search: Utils.isNullOrEmpty(searchText) ? null : searchText }, queryParamsHandling: "merge", replaceUrl: true, - }) + }), ); this.currentSearchText$ = this.route.queryParams.pipe(map((queryParams) => queryParams.search)); const allCollectionsWithoutUnassigned$ = organizationId$.pipe( switchMap((orgId) => this.collectionAdminService.getAll(orgId)), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const allCollections$ = combineLatest([organizationId$, allCollectionsWithoutUnassigned$]).pipe( @@ -244,12 +244,12 @@ export class VaultComponent implements OnInit, OnDestroy { noneCollection.id = Unassigned; noneCollection.organizationId = organizationId; return allCollections.concat(noneCollection); - }) + }), ); const allGroups$ = organizationId$.pipe( switchMap((organizationId) => this.groupService.getAll(organizationId)), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const allCiphers$ = organization$.pipe( @@ -259,12 +259,12 @@ export class VaultComponent implements OnInit, OnDestroy { ciphers = await this.cipherService.getAllFromApiForOrganization(organization.id); } else { ciphers = (await this.cipherService.getAllDecrypted()).filter( - (c) => c.organizationId === organization.id + (c) => c.organizationId === organization.id, ); } await this.searchService.indexCiphers(ciphers, organization.id); return ciphers; - }) + }), ); const ciphers$ = combineLatest([allCiphers$, filter$, this.currentSearchText$]).pipe( @@ -282,12 +282,12 @@ export class VaultComponent implements OnInit, OnDestroy { return ciphers.filter(filterFunction); }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const nestedCollections$ = allCollections$.pipe( map((collections) => getNestedCollectionTree(collections)), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const collections$ = combineLatest([nestedCollections$, filter$, this.currentSearchText$]).pipe( @@ -306,7 +306,7 @@ export class VaultComponent implements OnInit, OnDestroy { } else { const selectedCollection = ServiceUtils.getTreeNodeObjectFromList( collections, - filter.collectionId + filter.collectionId, ); collectionsToReturn = selectedCollection?.children.map((c) => c.node) ?? []; } @@ -316,14 +316,14 @@ export class VaultComponent implements OnInit, OnDestroy { collectionsToReturn, searchText, (collection) => collection.name, - (collection) => collection.id + (collection) => collection.id, ); } return collectionsToReturn; }), takeUntil(this.destroy$), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const selectedCollection$ = combineLatest([nestedCollections$, filter$]).pipe( @@ -339,7 +339,7 @@ export class VaultComponent implements OnInit, OnDestroy { return ServiceUtils.getTreeNodeObjectFromList(collections, filter.collectionId); }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); const showMissingCollectionPermissionMessage$ = combineLatest([ @@ -357,7 +357,7 @@ export class VaultComponent implements OnInit, OnDestroy { !organization.canUseAdminCollections) ); }), - shareReplay({ refCount: true, bufferSize: 1 }) + shareReplay({ refCount: true, bufferSize: 1 }), ); firstSetup$ @@ -378,7 +378,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("unknownCipher") + this.i18nService.t("unknownCipher"), ); this.router.navigate([], { queryParams: { cipherId: null, itemId: null }, @@ -386,7 +386,7 @@ export class VaultComponent implements OnInit, OnDestroy { }); } }), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe(); @@ -405,7 +405,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("unknownCipher") + this.i18nService.t("unknownCipher"), ); this.router.navigate([], { queryParams: { viewEvents: null }, @@ -413,7 +413,7 @@ export class VaultComponent implements OnInit, OnDestroy { }); } }), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe(); @@ -431,9 +431,9 @@ export class VaultComponent implements OnInit, OnDestroy { collections$, selectedCollection$, showMissingCollectionPermissionMessage$, - ]) + ]), ), - takeUntil(this.destroy$) + takeUntil(this.destroy$), ) .subscribe( ([ @@ -463,7 +463,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.refreshing = false; this.performingInitialLoad = false; - } + }, ); } @@ -550,7 +550,7 @@ export class VaultComponent implements OnInit, OnDestroy { comp.onDeletedAttachment .pipe(takeUntil(this.destroy$)) .subscribe(() => (madeAttachmentChanges = true)); - } + }, ); modal.onClosed.pipe(takeUntil(this.destroy$)).subscribe(() => { @@ -575,13 +575,13 @@ export class VaultComponent implements OnInit, OnDestroy { modal.close(); this.refresh(); }); - } + }, ); } async addCipher() { const collections = (await firstValueFrom(this.vaultFilterService.filteredCollections$)).filter( - (c) => !c.readOnly && c.id != Unassigned + (c) => !c.readOnly && c.id != Unassigned, ); await this.editCipher(null, (comp) => { @@ -599,14 +599,14 @@ export class VaultComponent implements OnInit, OnDestroy { async editCipher( cipher: CipherView, - additionalComponentParameters?: (comp: AddEditComponent) => void + additionalComponentParameters?: (comp: AddEditComponent) => void, ) { return this.editCipherId(cipher?.id, additionalComponentParameters); } async editCipherId( cipherId: string, - additionalComponentParameters?: (comp: AddEditComponent) => void + additionalComponentParameters?: (comp: AddEditComponent) => void, ) { const cipher = await this.cipherService.get(cipherId); // if cipher exists (cipher is null when new) and MP reprompt @@ -647,7 +647,7 @@ export class VaultComponent implements OnInit, OnDestroy { : (comp) => { defaultComponentParameters(comp); additionalComponentParameters(comp); - } + }, ); modal.onClosedPromise().then(() => { @@ -671,7 +671,7 @@ export class VaultComponent implements OnInit, OnDestroy { } const collections = (await firstValueFrom(this.vaultFilterService.filteredCollections$)).filter( - (c) => !c.readOnly && c.id != Unassigned + (c) => !c.readOnly && c.id != Unassigned, ); await this.editCipher(cipher, (comp) => { @@ -710,7 +710,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("nothingSelected") + this.i18nService.t("nothingSelected"), ); return; } @@ -742,7 +742,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "success", null, - this.i18nService.t(permanent ? "permanentlyDeletedItem" : "deletedItem") + this.i18nService.t(permanent ? "permanentlyDeletedItem" : "deletedItem"), ); this.refresh(); } catch (e) { @@ -753,16 +753,13 @@ export class VaultComponent implements OnInit, OnDestroy { async deleteCollection(collection: CollectionView): Promise { const flexibleCollectionsEnabled = await this.configService.getFeatureFlag( FeatureFlag.FlexibleCollections, - false + false, ); - if ( - (flexibleCollectionsEnabled || !this.organization.canDeleteAssignedCollections) && - !this.organization.canDeleteAnyCollection - ) { + if (collection.canDelete(this.organization, flexibleCollectionsEnabled)) { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("missingPermissions") + this.i18nService.t("missingPermissions"), ); return; } @@ -780,7 +777,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "success", null, - this.i18nService.t("deletedCollectionId", collection.name) + this.i18nService.t("deletedCollectionId", collection.name), ); // Navigate away if we deleted the colletion we were viewing @@ -801,7 +798,7 @@ export class VaultComponent implements OnInit, OnDestroy { async bulkDelete( ciphers: CipherView[], collections: CollectionView[], - organization: Organization + organization: Organization, ) { if (!(await this.repromptCipher(ciphers))) { return; @@ -811,7 +808,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("nothingSelected") + this.i18nService.t("nothingSelected"), ); return; } @@ -867,7 +864,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "info", null, - this.i18nService.t("valueCopied", this.i18nService.t(typeI18nKey)) + this.i18nService.t("valueCopied", this.i18nService.t(typeI18nKey)), ); if (field === "password") { @@ -913,7 +910,7 @@ export class VaultComponent implements OnInit, OnDestroy { this.platformUtilsService.showToast( "error", this.i18nService.t("errorOccurred"), - this.i18nService.t("nothingSelected") + this.i18nService.t("nothingSelected"), ); return; }