mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[PM-22100] Enforce restrictions based on collection type (#15336)
* enforce restrictions based on collection type, set default collection type * fix ts strict errors * fix default collection enforcement in vault header * enforce default collection restrictions in vault collection row * enforce default collection restrictions in AC vault header * enforce default collection restriction for select all * fix ts strict error * switch to signal, fix feature flag * fix story * clean up * remove feature flag, move check for defaultCollecion to CollecitonView * fix test * remove unused configService * fix test: coerce null to undefined for collection Id * clean up leaky abstraction for default collection * fix ts-strict error * fix parens * rename defaultCollection getter * clean up
This commit is contained in:
@@ -237,7 +237,7 @@ export class VaultPopupListFiltersService {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (filters.collection && !cipher.collectionIds?.includes(filters.collection.id)) {
|
||||
if (filters.collection && !cipher.collectionIds?.includes(filters.collection.id!)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -25,62 +25,67 @@
|
||||
</bit-breadcrumbs>
|
||||
|
||||
<ng-container slot="title-suffix">
|
||||
<ng-container
|
||||
*ngIf="
|
||||
collection != null && (canEditCollection || canDeleteCollection || canViewCollectionInfo)
|
||||
"
|
||||
>
|
||||
<button
|
||||
bitIconButton="bwi-angle-down"
|
||||
[bitMenuTriggerFor]="editCollectionMenu"
|
||||
size="small"
|
||||
type="button"
|
||||
></button>
|
||||
<bit-menu #editCollectionMenu>
|
||||
<ng-container *ngIf="canEditCollection">
|
||||
@if (
|
||||
collection != null && (canEditCollection || canDeleteCollection || canViewCollectionInfo)
|
||||
) {
|
||||
<ng-container>
|
||||
<button
|
||||
bitIconButton="bwi-angle-down"
|
||||
[bitMenuTriggerFor]="editCollectionMenu"
|
||||
size="small"
|
||||
type="button"
|
||||
></button>
|
||||
<bit-menu #editCollectionMenu>
|
||||
<ng-container *ngIf="canEditCollection">
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Info, false)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-pencil-square" aria-hidden="true"></i>
|
||||
{{ "editInfo" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Access, false)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-users" aria-hidden="true"></i>
|
||||
{{ "access" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!canEditCollection && canViewCollectionInfo">
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Info, true)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-pencil-square" aria-hidden="true"></i>
|
||||
{{ "viewInfo" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Access, true)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-users" aria-hidden="true"></i>
|
||||
{{ "viewAccess" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="canDeleteCollection"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Info, false)"
|
||||
(click)="deleteCollection()"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-pencil-square" aria-hidden="true"></i>
|
||||
{{ "editInfo" | i18n }}
|
||||
<span class="tw-text-danger">
|
||||
<i class="bwi bwi-fw bwi-trash" aria-hidden="true"></i>
|
||||
{{ "delete" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Access, false)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-users" aria-hidden="true"></i>
|
||||
{{ "access" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<ng-container *ngIf="!canEditCollection && canViewCollectionInfo">
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Info, true)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-pencil-square" aria-hidden="true"></i>
|
||||
{{ "viewInfo" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Access, true)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-users" aria-hidden="true"></i>
|
||||
{{ "viewAccess" | i18n }}
|
||||
</button>
|
||||
</ng-container>
|
||||
<button type="button" *ngIf="canDeleteCollection" bitMenuItem (click)="deleteCollection()">
|
||||
<span class="tw-text-danger">
|
||||
<i class="bwi bwi-fw bwi-trash" aria-hidden="true"></i>
|
||||
{{ "delete" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
</bit-menu>
|
||||
</ng-container>
|
||||
</bit-menu>
|
||||
</ng-container>
|
||||
}
|
||||
<small *ngIf="loading">
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
|
||||
@@ -1,14 +1,15 @@
|
||||
<td bitCell [ngClass]="RowHeightClass" class="tw-min-w-fit">
|
||||
<input
|
||||
type="checkbox"
|
||||
bitCheckbox
|
||||
appStopProp
|
||||
*ngIf="showCheckbox"
|
||||
[disabled]="disabled"
|
||||
[checked]="checked"
|
||||
(change)="$event ? this.checkedToggled.next() : null"
|
||||
[attr.aria-label]="'collectionItemSelect' | i18n"
|
||||
/>
|
||||
@if (this.canEditCollection || this.canDeleteCollection) {
|
||||
<input
|
||||
type="checkbox"
|
||||
bitCheckbox
|
||||
appStopProp
|
||||
[disabled]="disabled"
|
||||
[checked]="checked"
|
||||
(change)="$event ? this.checkedToggled.next() : null"
|
||||
[attr.aria-label]="'collectionItemSelect' | i18n"
|
||||
/>
|
||||
}
|
||||
</td>
|
||||
<td bitCell [ngClass]="RowHeightClass" class="tw-min-w-fit">
|
||||
<div aria-hidden="true">
|
||||
@@ -57,16 +58,17 @@
|
||||
</p>
|
||||
</td>
|
||||
<td bitCell [ngClass]="RowHeightClass" class="tw-text-right">
|
||||
<button
|
||||
*ngIf="canEditCollection || canDeleteCollection || canViewCollectionInfo"
|
||||
[disabled]="disabled"
|
||||
[bitMenuTriggerFor]="collectionOptions"
|
||||
size="small"
|
||||
bitIconButton="bwi-ellipsis-v"
|
||||
type="button"
|
||||
appA11yTitle="{{ 'options' | i18n }}"
|
||||
appStopProp
|
||||
></button>
|
||||
@if (canEditCollection || canDeleteCollection || canViewCollectionInfo) {
|
||||
<button
|
||||
[disabled]="disabled"
|
||||
[bitMenuTriggerFor]="collectionOptions"
|
||||
size="small"
|
||||
bitIconButton="bwi-ellipsis-v"
|
||||
type="button"
|
||||
appA11yTitle="{{ 'options' | i18n }}"
|
||||
appStopProp
|
||||
></button>
|
||||
}
|
||||
<bit-menu #collectionOptions>
|
||||
<ng-container *ngIf="canEditCollection">
|
||||
<button type="button" bitMenuItem (click)="edit(false)">
|
||||
|
||||
@@ -105,12 +105,4 @@ export class VaultCollectionRowComponent<C extends CipherViewLike> {
|
||||
protected deleteCollection() {
|
||||
this.onEvent.next({ type: "delete", items: [{ collection: this.collection }] });
|
||||
}
|
||||
|
||||
protected get showCheckbox() {
|
||||
if (this.collection?.id === Unassigned) {
|
||||
return false; // Never show checkbox for Unassigned
|
||||
}
|
||||
|
||||
return this.canEditCollection || this.canDeleteCollection;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,41 +22,48 @@
|
||||
</bit-breadcrumbs>
|
||||
|
||||
<ng-container slot="title-suffix">
|
||||
<ng-container *ngIf="collection != null && (canEditCollection || canDeleteCollection)">
|
||||
<button
|
||||
bitIconButton="bwi-angle-down"
|
||||
[bitMenuTriggerFor]="editCollectionMenu"
|
||||
size="small"
|
||||
type="button"
|
||||
aria-haspopup="true"
|
||||
></button>
|
||||
<bit-menu #editCollectionMenu>
|
||||
@if (collection != null && (canEditCollection || canDeleteCollection)) {
|
||||
<ng-container>
|
||||
<button
|
||||
bitIconButton="bwi-angle-down"
|
||||
[bitMenuTriggerFor]="editCollectionMenu"
|
||||
size="small"
|
||||
type="button"
|
||||
*ngIf="canEditCollection"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Info)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-pencil-square" aria-hidden="true"></i>
|
||||
{{ "editInfo" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="canEditCollection"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Access)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-users" aria-hidden="true"></i>
|
||||
{{ "access" | i18n }}
|
||||
</button>
|
||||
<button type="button" *ngIf="canDeleteCollection" bitMenuItem (click)="deleteCollection()">
|
||||
<span class="tw-text-danger">
|
||||
<i class="bwi bwi-fw bwi-trash" aria-hidden="true"></i>
|
||||
{{ "delete" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
</bit-menu>
|
||||
</ng-container>
|
||||
aria-haspopup="true"
|
||||
></button>
|
||||
<bit-menu #editCollectionMenu>
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="canEditCollection"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Info)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-pencil-square" aria-hidden="true"></i>
|
||||
{{ "editInfo" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="canEditCollection"
|
||||
bitMenuItem
|
||||
(click)="editCollection(CollectionDialogTabType.Access)"
|
||||
>
|
||||
<i class="bwi bwi-fw bwi-users" aria-hidden="true"></i>
|
||||
{{ "access" | i18n }}
|
||||
</button>
|
||||
<button
|
||||
type="button"
|
||||
*ngIf="canDeleteCollection"
|
||||
bitMenuItem
|
||||
(click)="deleteCollection()"
|
||||
>
|
||||
<span class="tw-text-danger">
|
||||
<i class="bwi bwi-fw bwi-trash" aria-hidden="true"></i>
|
||||
{{ "delete" | i18n }}
|
||||
</span>
|
||||
</button>
|
||||
</bit-menu>
|
||||
</ng-container>
|
||||
}
|
||||
<small *ngIf="loading">
|
||||
<i
|
||||
class="bwi bwi-spinner bwi-spin tw-text-muted"
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// FIXME: Update this file to be type safe and remove this and next line
|
||||
// @ts-strict-ignore
|
||||
import { CommonModule } from "@angular/common";
|
||||
import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output } from "@angular/core";
|
||||
import { Router } from "@angular/router";
|
||||
@@ -60,10 +58,10 @@ export class VaultHeaderComponent {
|
||||
* Boolean to determine the loading state of the header.
|
||||
* Shows a loading spinner if set to true
|
||||
*/
|
||||
@Input() loading: boolean;
|
||||
@Input() loading: boolean = true;
|
||||
|
||||
/** Current active filter */
|
||||
@Input() filter: RoutedVaultFilterModel;
|
||||
@Input() filter: RoutedVaultFilterModel | undefined;
|
||||
|
||||
/** All organizations that can be shown */
|
||||
@Input() organizations: Organization[] = [];
|
||||
@@ -72,7 +70,7 @@ export class VaultHeaderComponent {
|
||||
@Input() collection?: TreeNode<CollectionView>;
|
||||
|
||||
/** Whether 'Collection' option is shown in the 'New' dropdown */
|
||||
@Input() canCreateCollections: boolean;
|
||||
@Input() canCreateCollections: boolean = false;
|
||||
|
||||
/** Emits an event when the new item button is clicked in the header */
|
||||
@Output() onAddCipher = new EventEmitter<CipherType | undefined>();
|
||||
@@ -106,7 +104,7 @@ export class VaultHeaderComponent {
|
||||
return this.collection.node.organizationId;
|
||||
}
|
||||
|
||||
if (this.filter.organizationId !== undefined) {
|
||||
if (this.filter?.organizationId !== undefined) {
|
||||
return this.filter.organizationId;
|
||||
}
|
||||
|
||||
@@ -119,10 +117,14 @@ export class VaultHeaderComponent {
|
||||
}
|
||||
|
||||
protected get showBreadcrumbs() {
|
||||
return this.filter.collectionId !== undefined && this.filter.collectionId !== All;
|
||||
return this.filter?.collectionId !== undefined && this.filter.collectionId !== All;
|
||||
}
|
||||
|
||||
protected get title() {
|
||||
if (this.filter === undefined) {
|
||||
return "";
|
||||
}
|
||||
|
||||
if (this.filter.collectionId === Unassigned) {
|
||||
return this.i18nService.t("unassigned");
|
||||
}
|
||||
@@ -144,7 +146,7 @@ export class VaultHeaderComponent {
|
||||
}
|
||||
|
||||
protected get icon() {
|
||||
return this.filter.collectionId && this.filter.collectionId !== All
|
||||
return this.filter?.collectionId && this.filter.collectionId !== All
|
||||
? "bwi-collection-shared"
|
||||
: "";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user