mirror of
https://github.com/bitwarden/browser.git
synced 2024-11-25 12:15:18 +01:00
[AC-2647] Remove Flexible Collections MVP code (#9518)
* chore: organization.ts, remove refs to flexibleCollections and isManager, refs AC-2647 * chore: clean up callers of removed methods from organization.ts, refs AC-2647 * chore: access-selector, remove fc input and update permissionList param, refs AC-2647 * chore: update permissionList caller, update group-add-edit fc refs, and remove accessAll, refs AC-2647 * chore: update member-dialog fc callers, refs AC-2647 * chore: update bulk-collections-dialog fc callers, refs AC-2647 * chore: update collection-dialog fc callers, refs AC-2647 * chore: update simple fc caller to misc files, refs AC-2647 * chore: update member-dialog fc callers, refs AC-2647 * chore: remove accessAll references and update callers, refs AC-2647 * chore: update comment to specify v1 usage, refs AC-2647 * chore: remove unused message keys and code calls to use those messages, refs AC-2647 * chore: remove readonly false from access-selector model map function, refs AC-2647
This commit is contained in:
parent
19f2d2aefc
commit
b169207b74
@ -80,7 +80,6 @@ export class InternalGroupService extends GroupService {
|
|||||||
async save(group: GroupView): Promise<GroupView> {
|
async save(group: GroupView): Promise<GroupView> {
|
||||||
const request = new GroupRequest();
|
const request = new GroupRequest();
|
||||||
request.name = group.name;
|
request.name = group.name;
|
||||||
request.accessAll = group.accessAll;
|
|
||||||
request.users = group.members;
|
request.users = group.members;
|
||||||
request.collections = group.collections.map(
|
request.collections = group.collections.map(
|
||||||
(c) => new SelectionReadOnlyRequest(c.id, c.readOnly, c.hidePasswords, c.manage),
|
(c) => new SelectionReadOnlyRequest(c.id, c.readOnly, c.hidePasswords, c.manage),
|
||||||
|
@ -2,7 +2,6 @@ import { SelectionReadOnlyRequest } from "@bitwarden/common/admin-console/models
|
|||||||
|
|
||||||
export class GroupRequest {
|
export class GroupRequest {
|
||||||
name: string;
|
name: string;
|
||||||
accessAll: boolean;
|
|
||||||
collections: SelectionReadOnlyRequest[] = [];
|
collections: SelectionReadOnlyRequest[] = [];
|
||||||
users: string[] = [];
|
users: string[] = [];
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,6 @@ export class GroupResponse extends BaseResponse {
|
|||||||
id: string;
|
id: string;
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
name: string;
|
name: string;
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* To be removed after Flexible Collections.
|
|
||||||
**/
|
|
||||||
accessAll: boolean;
|
|
||||||
externalId: string;
|
externalId: string;
|
||||||
|
|
||||||
constructor(response: any) {
|
constructor(response: any) {
|
||||||
@ -17,7 +12,6 @@ export class GroupResponse extends BaseResponse {
|
|||||||
this.id = this.getResponseProperty("Id");
|
this.id = this.getResponseProperty("Id");
|
||||||
this.organizationId = this.getResponseProperty("OrganizationId");
|
this.organizationId = this.getResponseProperty("OrganizationId");
|
||||||
this.name = this.getResponseProperty("Name");
|
this.name = this.getResponseProperty("Name");
|
||||||
this.accessAll = this.getResponseProperty("AccessAll");
|
|
||||||
this.externalId = this.getResponseProperty("ExternalId");
|
this.externalId = this.getResponseProperty("ExternalId");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,6 @@ export class UserAdminService {
|
|||||||
|
|
||||||
async save(user: OrganizationUserAdminView): Promise<void> {
|
async save(user: OrganizationUserAdminView): Promise<void> {
|
||||||
const request = new OrganizationUserUpdateRequest();
|
const request = new OrganizationUserUpdateRequest();
|
||||||
request.accessAll = user.accessAll;
|
|
||||||
request.permissions = user.permissions;
|
request.permissions = user.permissions;
|
||||||
request.type = user.type;
|
request.type = user.type;
|
||||||
request.collections = user.collections;
|
request.collections = user.collections;
|
||||||
@ -54,7 +53,6 @@ export class UserAdminService {
|
|||||||
async invite(emails: string[], user: OrganizationUserAdminView): Promise<void> {
|
async invite(emails: string[], user: OrganizationUserAdminView): Promise<void> {
|
||||||
const request = new OrganizationUserInviteRequest();
|
const request = new OrganizationUserInviteRequest();
|
||||||
request.emails = emails;
|
request.emails = emails;
|
||||||
request.accessAll = user.accessAll;
|
|
||||||
request.permissions = user.permissions;
|
request.permissions = user.permissions;
|
||||||
request.type = user.type;
|
request.type = user.type;
|
||||||
request.collections = user.collections;
|
request.collections = user.collections;
|
||||||
@ -77,7 +75,6 @@ export class UserAdminService {
|
|||||||
view.type = u.type;
|
view.type = u.type;
|
||||||
view.status = u.status;
|
view.status = u.status;
|
||||||
view.externalId = u.externalId;
|
view.externalId = u.externalId;
|
||||||
view.accessAll = u.accessAll;
|
|
||||||
view.permissions = u.permissions;
|
view.permissions = u.permissions;
|
||||||
view.resetPasswordEnrolled = u.resetPasswordEnrolled;
|
view.resetPasswordEnrolled = u.resetPasswordEnrolled;
|
||||||
view.collections = u.collections.map((c) => ({
|
view.collections = u.collections.map((c) => ({
|
||||||
|
@ -8,12 +8,6 @@ export class GroupView implements View {
|
|||||||
id: string;
|
id: string;
|
||||||
organizationId: string;
|
organizationId: string;
|
||||||
name: string;
|
name: string;
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* To be removed after Flexible Collections.
|
|
||||||
* This will always return `false` if Flexible Collections is enabled.
|
|
||||||
**/
|
|
||||||
accessAll: boolean;
|
|
||||||
externalId: string;
|
externalId: string;
|
||||||
collections: CollectionAccessSelectionView[] = [];
|
collections: CollectionAccessSelectionView[] = [];
|
||||||
members: string[] = [];
|
members: string[] = [];
|
||||||
|
@ -13,12 +13,6 @@ export class OrganizationUserAdminView {
|
|||||||
type: OrganizationUserType;
|
type: OrganizationUserType;
|
||||||
status: OrganizationUserStatusType;
|
status: OrganizationUserStatusType;
|
||||||
externalId: string;
|
externalId: string;
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* To be removed after Flexible Collections.
|
|
||||||
* This will always return `false` if Flexible Collections is enabled.
|
|
||||||
**/
|
|
||||||
accessAll: boolean;
|
|
||||||
permissions: PermissionsApi;
|
permissions: PermissionsApi;
|
||||||
resetPasswordEnrolled: boolean;
|
resetPasswordEnrolled: boolean;
|
||||||
hasMasterPassword: boolean;
|
hasMasterPassword: boolean;
|
||||||
|
@ -12,12 +12,6 @@ export class OrganizationUserView {
|
|||||||
userId: string;
|
userId: string;
|
||||||
type: OrganizationUserType;
|
type: OrganizationUserType;
|
||||||
status: OrganizationUserStatusType;
|
status: OrganizationUserStatusType;
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* To be removed after Flexible Collections.
|
|
||||||
* This will always return `false` if Flexible Collections is enabled.
|
|
||||||
**/
|
|
||||||
accessAll: boolean;
|
|
||||||
permissions: PermissionsApi;
|
permissions: PermissionsApi;
|
||||||
resetPasswordEnrolled: boolean;
|
resetPasswordEnrolled: boolean;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
<bit-nav-item
|
<bit-nav-item
|
||||||
icon="bwi-collection"
|
icon="bwi-collection"
|
||||||
[text]="(organization.flexibleCollections ? 'collections' : 'vault') | i18n"
|
[text]="'collections' | i18n"
|
||||||
route="vault"
|
route="vault"
|
||||||
*ngIf="canShowVaultTab(organization)"
|
*ngIf="canShowVaultTab(organization)"
|
||||||
>
|
>
|
||||||
|
@ -45,7 +45,6 @@
|
|||||||
[columnHeader]="'member' | i18n"
|
[columnHeader]="'member' | i18n"
|
||||||
[selectorLabelText]="'selectMembers' | i18n"
|
[selectorLabelText]="'selectMembers' | i18n"
|
||||||
[emptySelectionText]="'noMembersAdded' | i18n"
|
[emptySelectionText]="'noMembersAdded' | i18n"
|
||||||
[flexibleCollectionsEnabled]="flexibleCollectionsEnabled$ | async"
|
|
||||||
></bit-access-selector>
|
></bit-access-selector>
|
||||||
</bit-tab>
|
</bit-tab>
|
||||||
|
|
||||||
@ -56,24 +55,14 @@
|
|||||||
{{ "restrictedCollectionAssignmentDesc" | i18n }}
|
{{ "restrictedCollectionAssignmentDesc" | i18n }}
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
<div *ngIf="!(flexibleCollectionsEnabled$ | async)" class="tw-my-3">
|
<bit-access-selector
|
||||||
<input type="checkbox" formControlName="accessAll" id="accessAll" />
|
formControlName="collections"
|
||||||
<label class="tw-mb-0 tw-text-lg" for="accessAll">{{
|
[items]="collections"
|
||||||
"accessAllCollectionsDesc" | i18n
|
[permissionMode]="PermissionMode.Edit"
|
||||||
}}</label>
|
[columnHeader]="'collection' | i18n"
|
||||||
<p class="tw-my-0 tw-text-muted">{{ "accessAllCollectionsHelp" | i18n }}</p>
|
[selectorLabelText]="'selectCollections' | i18n"
|
||||||
</div>
|
[emptySelectionText]="'noCollectionsAdded' | i18n"
|
||||||
<ng-container *ngIf="!groupForm.value.accessAll">
|
></bit-access-selector>
|
||||||
<bit-access-selector
|
|
||||||
formControlName="collections"
|
|
||||||
[items]="collections"
|
|
||||||
[permissionMode]="PermissionMode.Edit"
|
|
||||||
[columnHeader]="'collection' | i18n"
|
|
||||||
[selectorLabelText]="'selectCollections' | i18n"
|
|
||||||
[emptySelectionText]="'noCollectionsAdded' | i18n"
|
|
||||||
[flexibleCollectionsEnabled]="flexibleCollectionsEnabled$ | async"
|
|
||||||
></bit-access-selector>
|
|
||||||
</ng-container>
|
|
||||||
</bit-tab>
|
</bit-tab>
|
||||||
</bit-tab-group>
|
</bit-tab-group>
|
||||||
</div>
|
</div>
|
||||||
|
@ -96,9 +96,6 @@ export class GroupAddEditComponent implements OnInit, OnDestroy {
|
|||||||
private organization$ = this.organizationService
|
private organization$ = this.organizationService
|
||||||
.get$(this.organizationId)
|
.get$(this.organizationId)
|
||||||
.pipe(shareReplay({ refCount: true }));
|
.pipe(shareReplay({ refCount: true }));
|
||||||
protected flexibleCollectionsEnabled$ = this.organization$.pipe(
|
|
||||||
map((o) => o?.flexibleCollections),
|
|
||||||
);
|
|
||||||
private flexibleCollectionsV1Enabled$ = this.configService.getFeatureFlag$(
|
private flexibleCollectionsV1Enabled$ = this.configService.getFeatureFlag$(
|
||||||
FeatureFlag.FlexibleCollectionsV1,
|
FeatureFlag.FlexibleCollectionsV1,
|
||||||
);
|
);
|
||||||
@ -114,7 +111,6 @@ export class GroupAddEditComponent implements OnInit, OnDestroy {
|
|||||||
group: GroupView;
|
group: GroupView;
|
||||||
|
|
||||||
groupForm = this.formBuilder.group({
|
groupForm = this.formBuilder.group({
|
||||||
accessAll: [false],
|
|
||||||
name: ["", [Validators.required, Validators.maxLength(100)]],
|
name: ["", [Validators.required, Validators.maxLength(100)]],
|
||||||
externalId: this.formBuilder.control({ value: "", disabled: true }),
|
externalId: this.formBuilder.control({ value: "", disabled: true }),
|
||||||
members: [[] as AccessItemValue[]],
|
members: [[] as AccessItemValue[]],
|
||||||
@ -188,7 +184,7 @@ export class GroupAddEditComponent implements OnInit, OnDestroy {
|
|||||||
this.flexibleCollectionsV1Enabled$,
|
this.flexibleCollectionsV1Enabled$,
|
||||||
]).pipe(
|
]).pipe(
|
||||||
map(([organization, flexibleCollectionsV1Enabled]) => {
|
map(([organization, flexibleCollectionsV1Enabled]) => {
|
||||||
if (!flexibleCollectionsV1Enabled || !organization.flexibleCollections) {
|
if (!flexibleCollectionsV1Enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +272,6 @@ export class GroupAddEditComponent implements OnInit, OnDestroy {
|
|||||||
this.groupForm.patchValue({
|
this.groupForm.patchValue({
|
||||||
name: this.group.name,
|
name: this.group.name,
|
||||||
externalId: this.group.externalId,
|
externalId: this.group.externalId,
|
||||||
accessAll: this.group.accessAll,
|
|
||||||
members: this.group.members.map((m) => ({
|
members: this.group.members.map((m) => ({
|
||||||
id: m,
|
id: m,
|
||||||
type: AccessItemType.Member,
|
type: AccessItemType.Member,
|
||||||
@ -328,12 +323,8 @@ export class GroupAddEditComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
const formValue = this.groupForm.value;
|
const formValue = this.groupForm.value;
|
||||||
groupView.name = formValue.name;
|
groupView.name = formValue.name;
|
||||||
groupView.accessAll = formValue.accessAll;
|
|
||||||
groupView.members = formValue.members?.map((m) => m.id) ?? [];
|
groupView.members = formValue.members?.map((m) => m.id) ?? [];
|
||||||
|
groupView.collections = formValue.collections.map((c) => convertToSelectionView(c));
|
||||||
if (!groupView.accessAll) {
|
|
||||||
groupView.collections = formValue.collections.map((c) => convertToSelectionView(c));
|
|
||||||
}
|
|
||||||
|
|
||||||
await this.groupService.save(groupView);
|
await this.groupService.save(groupView);
|
||||||
|
|
||||||
|
@ -74,12 +74,10 @@
|
|||||||
</td>
|
</td>
|
||||||
<td bitCell (click)="edit(g, ModalTabType.Collections)" class="tw-cursor-pointer">
|
<td bitCell (click)="edit(g, ModalTabType.Collections)" class="tw-cursor-pointer">
|
||||||
<bit-badge-list
|
<bit-badge-list
|
||||||
*ngIf="!g.details.accessAll"
|
|
||||||
[items]="g.collectionNames"
|
[items]="g.collectionNames"
|
||||||
[maxItems]="3"
|
[maxItems]="3"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
></bit-badge-list>
|
></bit-badge-list>
|
||||||
<span *ngIf="g.details.accessAll">{{ "all" | i18n }}</span>
|
|
||||||
</td>
|
</td>
|
||||||
<td bitCell>
|
<td bitCell>
|
||||||
<button
|
<button
|
||||||
|
@ -49,14 +49,6 @@
|
|||||||
<bit-label>{{ "user" | i18n }}</bit-label>
|
<bit-label>{{ "user" | i18n }}</bit-label>
|
||||||
<bit-hint>{{ "userDesc" | i18n }}</bit-hint>
|
<bit-hint>{{ "userDesc" | i18n }}</bit-hint>
|
||||||
</bit-radio-button>
|
</bit-radio-button>
|
||||||
<bit-radio-button
|
|
||||||
*ngIf="!organization.flexibleCollections"
|
|
||||||
id="userTypeManager"
|
|
||||||
[value]="organizationUserType.Manager"
|
|
||||||
>
|
|
||||||
<bit-label>{{ "manager" | i18n }}</bit-label>
|
|
||||||
<bit-hint>{{ "managerDesc" | i18n }}</bit-hint>
|
|
||||||
</bit-radio-button>
|
|
||||||
<bit-radio-button id="userTypeAdmin" [value]="organizationUserType.Admin">
|
<bit-radio-button id="userTypeAdmin" [value]="organizationUserType.Admin">
|
||||||
<bit-label>{{ "admin" | i18n }}</bit-label>
|
<bit-label>{{ "admin" | i18n }}</bit-label>
|
||||||
<bit-hint>{{ "adminDesc" | i18n }}</bit-hint>
|
<bit-hint>{{ "adminDesc" | i18n }}</bit-hint>
|
||||||
@ -91,140 +83,64 @@
|
|||||||
</bit-radio-button>
|
</bit-radio-button>
|
||||||
</bit-radio-group>
|
</bit-radio-group>
|
||||||
<ng-container *ngIf="customUserTypeSelected">
|
<ng-container *ngIf="customUserTypeSelected">
|
||||||
<ng-container *ngIf="!organization.flexibleCollections; else customPermissionsFC">
|
<div class="tw-grid tw-grid-cols-12 tw-gap-4" [formGroup]="permissionsGroup">
|
||||||
<h3 bitTypography="h3">
|
<div class="tw-col-span-4">
|
||||||
{{ "permissions" | i18n }}
|
<bit-form-control>
|
||||||
</h3>
|
<input type="checkbox" bitCheckbox formControlName="accessEventLogs" />
|
||||||
<div class="tw-grid tw-grid-cols-12 tw-gap-4" [formGroup]="permissionsGroup">
|
<bit-label>{{ "accessEventLogs" | i18n }}</bit-label>
|
||||||
<div class="tw-col-span-6">
|
</bit-form-control>
|
||||||
<div class="tw-mb-3">
|
<bit-form-control>
|
||||||
<bit-label class="tw-font-semibold">{{
|
<input type="checkbox" bitCheckbox formControlName="accessImportExport" />
|
||||||
"managerPermissions" | i18n
|
<bit-label>{{ "accessImportExport" | i18n }}</bit-label>
|
||||||
}}</bit-label>
|
</bit-form-control>
|
||||||
<hr class="tw-mb-2 tw-mr-2 tw-mt-0" />
|
<bit-form-control>
|
||||||
<app-nested-checkbox
|
<input type="checkbox" bitCheckbox formControlName="accessReports" />
|
||||||
parentId="manageAssignedCollections"
|
<bit-label>{{ "accessReports" | i18n }}</bit-label>
|
||||||
[checkboxes]="permissionsGroup.controls.manageAssignedCollectionsGroup"
|
</bit-form-control>
|
||||||
>
|
</div>
|
||||||
</app-nested-checkbox>
|
<div class="tw-col-span-4">
|
||||||
</div>
|
<app-nested-checkbox
|
||||||
</div>
|
parentId="manageAllCollections"
|
||||||
<div class="tw-col-span-6">
|
[checkboxes]="permissionsGroup.controls.manageAllCollectionsGroup"
|
||||||
<div class="tw-mb-3">
|
>
|
||||||
<bit-label class="tw-font-semibold">{{ "adminPermissions" | i18n }}</bit-label>
|
</app-nested-checkbox>
|
||||||
<hr class="tw-mb-2 tw-mr-2 tw-mt-0" />
|
</div>
|
||||||
<bit-form-control>
|
<div class="tw-col-span-4">
|
||||||
<input type="checkbox" bitCheckbox formControlName="accessEventLogs" />
|
<div class="tw-mb-3">
|
||||||
<bit-label>{{ "accessEventLogs" | i18n }}</bit-label>
|
<bit-form-control>
|
||||||
</bit-form-control>
|
<input type="checkbox" bitCheckbox formControlName="manageGroups" />
|
||||||
<bit-form-control>
|
<bit-label>{{ "manageGroups" | i18n }}</bit-label>
|
||||||
<input type="checkbox" bitCheckbox formControlName="accessImportExport" />
|
</bit-form-control>
|
||||||
<bit-label>{{ "accessImportExport" | i18n }}</bit-label>
|
<bit-form-control>
|
||||||
</bit-form-control>
|
<input type="checkbox" bitCheckbox formControlName="manageSso" />
|
||||||
<bit-form-control>
|
<bit-label>{{ "manageSso" | i18n }}</bit-label>
|
||||||
<input type="checkbox" bitCheckbox formControlName="accessReports" />
|
</bit-form-control>
|
||||||
<bit-label>{{ "accessReports" | i18n }}</bit-label>
|
<bit-form-control>
|
||||||
</bit-form-control>
|
<input type="checkbox" bitCheckbox formControlName="managePolicies" />
|
||||||
<app-nested-checkbox
|
<bit-label>{{ "managePolicies" | i18n }}</bit-label>
|
||||||
parentId="manageAllCollections"
|
</bit-form-control>
|
||||||
[checkboxes]="permissionsGroup.controls.manageAllCollectionsGroup"
|
<bit-form-control>
|
||||||
>
|
<input
|
||||||
</app-nested-checkbox>
|
id="manageUsers"
|
||||||
<bit-form-control>
|
type="checkbox"
|
||||||
<input type="checkbox" bitCheckbox formControlName="manageGroups" />
|
bitCheckbox
|
||||||
<bit-label>{{ "manageGroups" | i18n }}</bit-label>
|
formControlName="manageUsers"
|
||||||
</bit-form-control>
|
(change)="handleDependentPermissions()"
|
||||||
<bit-form-control>
|
/>
|
||||||
<input type="checkbox" bitCheckbox formControlName="manageSso" />
|
<bit-label>{{ "manageUsers" | i18n }}</bit-label>
|
||||||
<bit-label>{{ "manageSso" | i18n }}</bit-label>
|
</bit-form-control>
|
||||||
</bit-form-control>
|
<bit-form-control>
|
||||||
<bit-form-control>
|
<input
|
||||||
<input type="checkbox" bitCheckbox formControlName="managePolicies" />
|
type="checkbox"
|
||||||
<bit-label>{{ "managePolicies" | i18n }}</bit-label>
|
bitCheckbox
|
||||||
</bit-form-control>
|
formControlName="manageResetPassword"
|
||||||
<bit-form-control>
|
(change)="handleDependentPermissions()"
|
||||||
<input
|
/>
|
||||||
id="manageUsers"
|
<bit-label>{{ "manageAccountRecovery" | i18n }}</bit-label>
|
||||||
type="checkbox"
|
</bit-form-control>
|
||||||
bitCheckbox
|
|
||||||
formControlName="manageUsers"
|
|
||||||
(change)="handleDependentPermissions()"
|
|
||||||
/>
|
|
||||||
<bit-label>{{ "manageUsers" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
<bit-form-control>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
bitCheckbox
|
|
||||||
formControlName="manageResetPassword"
|
|
||||||
(change)="handleDependentPermissions()"
|
|
||||||
/>
|
|
||||||
<bit-label>{{ "manageAccountRecovery" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
</div>
|
||||||
<ng-template #customPermissionsFC>
|
|
||||||
<div class="tw-grid tw-grid-cols-12 tw-gap-4" [formGroup]="permissionsGroup">
|
|
||||||
<div class="tw-col-span-4">
|
|
||||||
<bit-form-control>
|
|
||||||
<input type="checkbox" bitCheckbox formControlName="accessEventLogs" />
|
|
||||||
<bit-label>{{ "accessEventLogs" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
<bit-form-control>
|
|
||||||
<input type="checkbox" bitCheckbox formControlName="accessImportExport" />
|
|
||||||
<bit-label>{{ "accessImportExport" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
<bit-form-control>
|
|
||||||
<input type="checkbox" bitCheckbox formControlName="accessReports" />
|
|
||||||
<bit-label>{{ "accessReports" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
</div>
|
|
||||||
<div class="tw-col-span-4">
|
|
||||||
<app-nested-checkbox
|
|
||||||
parentId="manageAllCollections"
|
|
||||||
[checkboxes]="permissionsGroup.controls.manageAllCollectionsGroup"
|
|
||||||
>
|
|
||||||
</app-nested-checkbox>
|
|
||||||
</div>
|
|
||||||
<div class="tw-col-span-4">
|
|
||||||
<div class="tw-mb-3">
|
|
||||||
<bit-form-control>
|
|
||||||
<input type="checkbox" bitCheckbox formControlName="manageGroups" />
|
|
||||||
<bit-label>{{ "manageGroups" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
<bit-form-control>
|
|
||||||
<input type="checkbox" bitCheckbox formControlName="manageSso" />
|
|
||||||
<bit-label>{{ "manageSso" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
<bit-form-control>
|
|
||||||
<input type="checkbox" bitCheckbox formControlName="managePolicies" />
|
|
||||||
<bit-label>{{ "managePolicies" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
<bit-form-control>
|
|
||||||
<input
|
|
||||||
id="manageUsers"
|
|
||||||
type="checkbox"
|
|
||||||
bitCheckbox
|
|
||||||
formControlName="manageUsers"
|
|
||||||
(change)="handleDependentPermissions()"
|
|
||||||
/>
|
|
||||||
<bit-label>{{ "manageUsers" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
<bit-form-control>
|
|
||||||
<input
|
|
||||||
type="checkbox"
|
|
||||||
bitCheckbox
|
|
||||||
formControlName="manageResetPassword"
|
|
||||||
(change)="handleDependentPermissions()"
|
|
||||||
/>
|
|
||||||
<bit-label>{{ "manageAccountRecovery" | i18n }}</bit-label>
|
|
||||||
</bit-form-control>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ng-template>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngIf="organization.useSecretsManager">
|
<ng-container *ngIf="organization.useSecretsManager">
|
||||||
<h3 class="tw-mt-4">
|
<h3 class="tw-mt-4">
|
||||||
@ -272,7 +188,6 @@
|
|||||||
[columnHeader]="'groups' | i18n"
|
[columnHeader]="'groups' | i18n"
|
||||||
[selectorLabelText]="'selectGroups' | i18n"
|
[selectorLabelText]="'selectGroups' | i18n"
|
||||||
[emptySelectionText]="'noGroupsAdded' | i18n"
|
[emptySelectionText]="'noGroupsAdded' | i18n"
|
||||||
[flexibleCollectionsEnabled]="organization.flexibleCollections"
|
|
||||||
[hideMultiSelect]="restrictEditingSelf$ | async"
|
[hideMultiSelect]="restrictEditingSelf$ | async"
|
||||||
></bit-access-selector>
|
></bit-access-selector>
|
||||||
</bit-tab>
|
</bit-tab>
|
||||||
@ -294,26 +209,7 @@
|
|||||||
{{ "restrictedCollectionAssignmentDesc" | i18n }}
|
{{ "restrictedCollectionAssignmentDesc" | i18n }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div *ngIf="!organization.flexibleCollections" class="tw-mb-6">
|
|
||||||
<bit-form-control>
|
|
||||||
<input type="checkbox" bitCheckbox formControlName="accessAllCollections" />
|
|
||||||
<bit-label>
|
|
||||||
{{ "accessAllCollectionsDesc" | i18n }}
|
|
||||||
<a
|
|
||||||
bitLink
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
appA11yTitle="{{ 'learnMore' | i18n }}"
|
|
||||||
href="https://bitwarden.com/help/user-types-access-control/#access-control"
|
|
||||||
>
|
|
||||||
<i class="bwi bwi-question-circle" aria-hidden="true"></i>
|
|
||||||
</a>
|
|
||||||
</bit-label>
|
|
||||||
<bit-hint>{{ "accessAllCollectionsHelp" | i18n }}</bit-hint>
|
|
||||||
</bit-form-control>
|
|
||||||
</div>
|
|
||||||
<bit-access-selector
|
<bit-access-selector
|
||||||
*ngIf="!accessAllCollections"
|
|
||||||
[permissionMode]="PermissionMode.Edit"
|
[permissionMode]="PermissionMode.Edit"
|
||||||
formControlName="access"
|
formControlName="access"
|
||||||
[showGroupColumn]="organization.useGroups"
|
[showGroupColumn]="organization.useGroups"
|
||||||
@ -321,7 +217,6 @@
|
|||||||
[columnHeader]="'collection' | i18n"
|
[columnHeader]="'collection' | i18n"
|
||||||
[selectorLabelText]="'selectCollections' | i18n"
|
[selectorLabelText]="'selectCollections' | i18n"
|
||||||
[emptySelectionText]="'noCollectionsAdded' | i18n"
|
[emptySelectionText]="'noCollectionsAdded' | i18n"
|
||||||
[flexibleCollectionsEnabled]="organization.flexibleCollections"
|
|
||||||
[hideMultiSelect]="restrictEditingSelf$ | async"
|
[hideMultiSelect]="restrictEditingSelf$ | async"
|
||||||
></bit-access-selector
|
></bit-access-selector
|
||||||
></bit-tab>
|
></bit-tab>
|
||||||
|
@ -99,7 +99,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
emails: [""],
|
emails: [""],
|
||||||
type: OrganizationUserType.User,
|
type: OrganizationUserType.User,
|
||||||
externalId: this.formBuilder.control({ value: "", disabled: true }),
|
externalId: this.formBuilder.control({ value: "", disabled: true }),
|
||||||
accessAllCollections: false,
|
|
||||||
accessSecretsManager: false,
|
accessSecretsManager: false,
|
||||||
access: [[] as AccessItemValue[]],
|
access: [[] as AccessItemValue[]],
|
||||||
groups: [[] as AccessItemValue[]],
|
groups: [[] as AccessItemValue[]],
|
||||||
@ -110,11 +109,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
protected canAssignAccessToAnyCollection$: Observable<boolean>;
|
protected canAssignAccessToAnyCollection$: Observable<boolean>;
|
||||||
|
|
||||||
protected permissionsGroup = this.formBuilder.group({
|
protected permissionsGroup = this.formBuilder.group({
|
||||||
manageAssignedCollectionsGroup: this.formBuilder.group<Record<string, boolean>>({
|
|
||||||
manageAssignedCollections: false,
|
|
||||||
editAssignedCollections: false,
|
|
||||||
deleteAssignedCollections: false,
|
|
||||||
}),
|
|
||||||
manageAllCollectionsGroup: this.formBuilder.group<Record<string, boolean>>({
|
manageAllCollectionsGroup: this.formBuilder.group<Record<string, boolean>>({
|
||||||
manageAllCollections: false,
|
manageAllCollections: false,
|
||||||
createNewCollections: false,
|
createNewCollections: false,
|
||||||
@ -137,10 +131,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
return this.formGroup.value.type === OrganizationUserType.Custom;
|
return this.formGroup.value.type === OrganizationUserType.Custom;
|
||||||
}
|
}
|
||||||
|
|
||||||
get accessAllCollections(): boolean {
|
|
||||||
return this.formGroup.value.accessAllCollections;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
@Inject(DIALOG_DATA) protected params: MemberDialogParams,
|
@Inject(DIALOG_DATA) protected params: MemberDialogParams,
|
||||||
private dialogRef: DialogRef<MemberDialogResult>,
|
private dialogRef: DialogRef<MemberDialogResult>,
|
||||||
@ -189,7 +179,7 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollectionsV1),
|
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollectionsV1),
|
||||||
]).pipe(
|
]).pipe(
|
||||||
map(([organization, flexibleCollectionsV1Enabled]) => {
|
map(([organization, flexibleCollectionsV1Enabled]) => {
|
||||||
if (!flexibleCollectionsV1Enabled || !organization.flexibleCollections) {
|
if (!flexibleCollectionsV1Enabled) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,13 +306,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
this.showNoMasterPasswordWarning =
|
this.showNoMasterPasswordWarning =
|
||||||
userDetails.status > OrganizationUserStatusType.Invited &&
|
userDetails.status > OrganizationUserStatusType.Invited &&
|
||||||
userDetails.hasMasterPassword === false;
|
userDetails.hasMasterPassword === false;
|
||||||
const assignedCollectionsPermissions = {
|
|
||||||
editAssignedCollections: userDetails.permissions.editAssignedCollections,
|
|
||||||
deleteAssignedCollections: userDetails.permissions.deleteAssignedCollections,
|
|
||||||
manageAssignedCollections:
|
|
||||||
userDetails.permissions.editAssignedCollections &&
|
|
||||||
userDetails.permissions.deleteAssignedCollections,
|
|
||||||
};
|
|
||||||
const allCollectionsPermissions = {
|
const allCollectionsPermissions = {
|
||||||
createNewCollections: userDetails.permissions.createNewCollections,
|
createNewCollections: userDetails.permissions.createNewCollections,
|
||||||
editAnyCollection: userDetails.permissions.editAnyCollection,
|
editAnyCollection: userDetails.permissions.editAnyCollection,
|
||||||
@ -342,7 +325,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
managePolicies: userDetails.permissions.managePolicies,
|
managePolicies: userDetails.permissions.managePolicies,
|
||||||
manageUsers: userDetails.permissions.manageUsers,
|
manageUsers: userDetails.permissions.manageUsers,
|
||||||
manageResetPassword: userDetails.permissions.manageResetPassword,
|
manageResetPassword: userDetails.permissions.manageResetPassword,
|
||||||
manageAssignedCollectionsGroup: assignedCollectionsPermissions,
|
|
||||||
manageAllCollectionsGroup: allCollectionsPermissions,
|
manageAllCollectionsGroup: allCollectionsPermissions,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -378,7 +360,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
this.formGroup.patchValue({
|
this.formGroup.patchValue({
|
||||||
type: userDetails.type,
|
type: userDetails.type,
|
||||||
externalId: userDetails.externalId,
|
externalId: userDetails.externalId,
|
||||||
accessAllCollections: userDetails.accessAll,
|
|
||||||
access: accessSelections,
|
access: accessSelections,
|
||||||
accessSecretsManager: userDetails.accessSecretsManager,
|
accessSecretsManager: userDetails.accessSecretsManager,
|
||||||
groups: groupAccessSelections,
|
groups: groupAccessSelections,
|
||||||
@ -414,10 +395,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
editAnyCollection: this.permissionsGroup.value.manageAllCollectionsGroup.editAnyCollection,
|
editAnyCollection: this.permissionsGroup.value.manageAllCollectionsGroup.editAnyCollection,
|
||||||
deleteAnyCollection:
|
deleteAnyCollection:
|
||||||
this.permissionsGroup.value.manageAllCollectionsGroup.deleteAnyCollection,
|
this.permissionsGroup.value.manageAllCollectionsGroup.deleteAnyCollection,
|
||||||
editAssignedCollections:
|
|
||||||
this.permissionsGroup.value.manageAssignedCollectionsGroup.editAssignedCollections,
|
|
||||||
deleteAssignedCollections:
|
|
||||||
this.permissionsGroup.value.manageAssignedCollectionsGroup.deleteAssignedCollections,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return Object.assign(p, partialPermissions);
|
return Object.assign(p, partialPermissions);
|
||||||
@ -467,7 +444,6 @@ export class MemberDialogComponent implements OnDestroy {
|
|||||||
const userView = new OrganizationUserAdminView();
|
const userView = new OrganizationUserAdminView();
|
||||||
userView.id = this.params.organizationUserId;
|
userView.id = this.params.organizationUserId;
|
||||||
userView.organizationId = this.params.organizationId;
|
userView.organizationId = this.params.organizationId;
|
||||||
userView.accessAll = this.accessAllCollections;
|
|
||||||
userView.type = this.formGroup.value.type;
|
userView.type = this.formGroup.value.type;
|
||||||
userView.permissions = this.setRequestPermissions(
|
userView.permissions = this.setRequestPermissions(
|
||||||
userView.permissions ?? new PermissionsApi(),
|
userView.permissions ?? new PermissionsApi(),
|
||||||
|
@ -190,12 +190,10 @@
|
|||||||
class="tw-cursor-pointer"
|
class="tw-cursor-pointer"
|
||||||
>
|
>
|
||||||
<bit-badge-list
|
<bit-badge-list
|
||||||
*ngIf="organization.useGroups || !u.accessAll"
|
|
||||||
[items]="organization.useGroups ? u.groupNames : u.collectionNames"
|
[items]="organization.useGroups ? u.groupNames : u.collectionNames"
|
||||||
[maxItems]="3"
|
[maxItems]="3"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
></bit-badge-list>
|
></bit-badge-list>
|
||||||
<span *ngIf="!organization.useGroups && u.accessAll">{{ "all" | i18n }}</span>
|
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td
|
<td
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
</button>
|
</button>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<form
|
<form
|
||||||
*ngIf="org && !loading && org.flexibleCollections"
|
*ngIf="org && !loading"
|
||||||
[bitSubmit]="submitCollectionManagement"
|
[bitSubmit]="submitCollectionManagement"
|
||||||
[formGroup]="collectionManagementFormGroup"
|
[formGroup]="collectionManagementFormGroup"
|
||||||
>
|
>
|
||||||
|
@ -110,15 +110,6 @@
|
|||||||
</ng-container>
|
</ng-container>
|
||||||
|
|
||||||
<ng-template #readOnlyPerm>
|
<ng-template #readOnlyPerm>
|
||||||
<div
|
|
||||||
*ngIf="item.accessAllItems"
|
|
||||||
class="tw-max-w-40 tw-overflow-hidden tw-overflow-ellipsis tw-whitespace-nowrap tw-border tw-border-solid tw-border-transparent tw-font-bold tw-text-muted"
|
|
||||||
[appA11yTitle]="accessAllLabelId(item) | i18n"
|
|
||||||
>
|
|
||||||
{{ "canEdit" | i18n }}
|
|
||||||
<i class="bwi bwi-filter tw-ml-1" aria-hidden="true"></i>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
<div
|
||||||
*ngIf="item.readonly || disabled"
|
*ngIf="item.readonly || disabled"
|
||||||
class="tw-max-w-40 tw-overflow-hidden tw-overflow-ellipsis tw-whitespace-nowrap tw-font-bold tw-text-muted"
|
class="tw-max-w-40 tw-overflow-hidden tw-overflow-ellipsis tw-whitespace-nowrap tw-font-bold tw-text-muted"
|
||||||
|
@ -75,7 +75,7 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On
|
|||||||
|
|
||||||
// The enable() above also enables the permission control, so we need to disable it again
|
// The enable() above also enables the permission control, so we need to disable it again
|
||||||
// Disable permission control if accessAllItems is enabled or not in Edit mode
|
// Disable permission control if accessAllItems is enabled or not in Edit mode
|
||||||
if (item.accessAllItems || this.permissionMode != PermissionMode.Edit) {
|
if (this.permissionMode != PermissionMode.Edit) {
|
||||||
controlRow.controls.permission.disable();
|
controlRow.controls.permission.disable();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,21 +196,11 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On
|
|||||||
*/
|
*/
|
||||||
@Input() showGroupColumn: boolean;
|
@Input() showGroupColumn: boolean;
|
||||||
|
|
||||||
/**
|
|
||||||
* Enable Flexible Collections changes (feature flag)
|
|
||||||
*/
|
|
||||||
@Input() set flexibleCollectionsEnabled(value: boolean) {
|
|
||||||
this._flexibleCollectionsEnabled = value;
|
|
||||||
this.permissionList = getPermissionList(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hide the multi-select so that new items cannot be added
|
* Hide the multi-select so that new items cannot be added
|
||||||
*/
|
*/
|
||||||
@Input() hideMultiSelect = false;
|
@Input() hideMultiSelect = false;
|
||||||
|
|
||||||
private _flexibleCollectionsEnabled: boolean;
|
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private readonly formBuilder: FormBuilder,
|
private readonly formBuilder: FormBuilder,
|
||||||
private readonly i18nService: I18nService,
|
private readonly i18nService: I18nService,
|
||||||
@ -275,7 +265,7 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On
|
|||||||
}
|
}
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.permissionList = getPermissionList(this._flexibleCollectionsEnabled);
|
this.permissionList = getPermissionList();
|
||||||
// Watch the internal formArray for changes and propagate them
|
// Watch the internal formArray for changes and propagate them
|
||||||
this.selectionList.formArray.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((v) => {
|
this.selectionList.formArray.valueChanges.pipe(takeUntil(this.destroy$)).subscribe((v) => {
|
||||||
if (!this.notifyOnChange || this.pauseChangeNotification) {
|
if (!this.notifyOnChange || this.pauseChangeNotification) {
|
||||||
@ -328,12 +318,8 @@ export class AccessSelectorComponent implements ControlValueAccessor, OnInit, On
|
|||||||
return this.permissionList.find((p) => p.perm == perm)?.labelId;
|
return this.permissionList.find((p) => p.perm == perm)?.labelId;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected accessAllLabelId(item: AccessItemView) {
|
|
||||||
return item.type == AccessItemType.Group ? "groupAccessAll" : "memberAccessAll";
|
|
||||||
}
|
|
||||||
|
|
||||||
protected canEditItemPermission(item: AccessItemView) {
|
protected canEditItemPermission(item: AccessItemView) {
|
||||||
return this.permissionMode == PermissionMode.Edit && !item.readonly && !item.accessAllItems;
|
return this.permissionMode == PermissionMode.Edit && !item.readonly;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _itemComparator(a: AccessItemView, b: AccessItemView) {
|
private _itemComparator(a: AccessItemView, b: AccessItemView) {
|
||||||
|
@ -34,12 +34,6 @@ export enum AccessItemType {
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
export type AccessItemView = SelectItemView & {
|
export type AccessItemView = SelectItemView & {
|
||||||
/**
|
|
||||||
* Flag that this group/member can access all items.
|
|
||||||
* This will disable the permission editor for this item.
|
|
||||||
*/
|
|
||||||
accessAllItems?: boolean;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flag that this item cannot be modified.
|
* Flag that this item cannot be modified.
|
||||||
* This will disable the permission editor and will keep
|
* This will disable the permission editor and will keep
|
||||||
@ -82,16 +76,14 @@ export type Permission = {
|
|||||||
labelId: string;
|
labelId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const getPermissionList = (flexibleCollectionsEnabled: boolean): Permission[] => {
|
export const getPermissionList = (): Permission[] => {
|
||||||
const permissions = [
|
const permissions = [
|
||||||
{ perm: CollectionPermission.View, labelId: "canView" },
|
{ perm: CollectionPermission.View, labelId: "canView" },
|
||||||
{ perm: CollectionPermission.ViewExceptPass, labelId: "canViewExceptPass" },
|
{ perm: CollectionPermission.ViewExceptPass, labelId: "canViewExceptPass" },
|
||||||
{ perm: CollectionPermission.Edit, labelId: "canEdit" },
|
{ perm: CollectionPermission.Edit, labelId: "canEdit" },
|
||||||
{ perm: CollectionPermission.EditExceptPass, labelId: "canEditExceptPass" },
|
{ perm: CollectionPermission.EditExceptPass, labelId: "canEditExceptPass" },
|
||||||
|
{ perm: CollectionPermission.Manage, labelId: "canManage" },
|
||||||
];
|
];
|
||||||
if (flexibleCollectionsEnabled) {
|
|
||||||
permissions.push({ perm: CollectionPermission.Manage, labelId: "canManage" });
|
|
||||||
}
|
|
||||||
|
|
||||||
return permissions;
|
return permissions;
|
||||||
};
|
};
|
||||||
@ -142,8 +134,6 @@ export function mapGroupToAccessItemView(group: GroupView): AccessItemView {
|
|||||||
type: AccessItemType.Group,
|
type: AccessItemType.Group,
|
||||||
listName: group.name,
|
listName: group.name,
|
||||||
labelName: group.name,
|
labelName: group.name,
|
||||||
accessAllItems: group.accessAll,
|
|
||||||
readonly: group.accessAll,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +147,5 @@ export function mapUserToAccessItemView(user: OrganizationUserUserDetailsRespons
|
|||||||
listName: user.name?.length > 0 ? `${user.name} (${user.email})` : user.email,
|
listName: user.name?.length > 0 ? `${user.name} (${user.email})` : user.email,
|
||||||
labelName: user.name ?? user.email,
|
labelName: user.name ?? user.email,
|
||||||
status: user.status,
|
status: user.status,
|
||||||
accessAllItems: user.accessAll,
|
|
||||||
readonly: user.accessAll,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -253,7 +253,6 @@ MemberGroupAccess.args = {
|
|||||||
type: AccessItemType.Group,
|
type: AccessItemType.Group,
|
||||||
listName: "Admin Group",
|
listName: "Admin Group",
|
||||||
labelName: "Admin Group",
|
labelName: "Admin Group",
|
||||||
accessAllItems: true,
|
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
@ -309,7 +308,6 @@ CollectionAccess.args = {
|
|||||||
type: AccessItemType.Group,
|
type: AccessItemType.Group,
|
||||||
listName: "Admin Group",
|
listName: "Admin Group",
|
||||||
labelName: "Admin Group",
|
labelName: "Admin Group",
|
||||||
accessAllItems: true,
|
|
||||||
readonly: true,
|
readonly: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -320,7 +318,6 @@ CollectionAccess.args = {
|
|||||||
status: OrganizationUserStatusType.Confirmed,
|
status: OrganizationUserStatusType.Confirmed,
|
||||||
role: OrganizationUserType.Admin,
|
role: OrganizationUserType.Admin,
|
||||||
email: "admin@email.com",
|
email: "admin@email.com",
|
||||||
accessAllItems: true,
|
|
||||||
readonly: true,
|
readonly: true,
|
||||||
},
|
},
|
||||||
]),
|
]),
|
||||||
|
@ -20,8 +20,6 @@ export class UserTypePipe implements PipeTransform {
|
|||||||
return this.i18nService.t("admin");
|
return this.i18nService.t("admin");
|
||||||
case OrganizationUserType.User:
|
case OrganizationUserType.User:
|
||||||
return this.i18nService.t("user");
|
return this.i18nService.t("user");
|
||||||
case OrganizationUserType.Manager:
|
|
||||||
return this.i18nService.t("manager");
|
|
||||||
case OrganizationUserType.Custom:
|
case OrganizationUserType.Custom:
|
||||||
return this.i18nService.t("custom");
|
return this.i18nService.t("custom");
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@
|
|||||||
</bit-form-field>
|
</bit-form-field>
|
||||||
</bit-tab>
|
</bit-tab>
|
||||||
<bit-tab label="{{ 'access' | i18n }}">
|
<bit-tab label="{{ 'access' | i18n }}">
|
||||||
<div class="tw-mb-3" *ngIf="organization.flexibleCollections">
|
<div class="tw-mb-3">
|
||||||
<ng-container *ngIf="dialogReadonly">
|
<ng-container *ngIf="dialogReadonly">
|
||||||
<span>{{ "readOnlyCollectionAccess" | i18n }}</span>
|
<span>{{ "readOnlyCollectionAccess" | i18n }}</span>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@ -107,7 +107,6 @@
|
|||||||
[selectorLabelText]="'selectGroupsAndMembers' | i18n"
|
[selectorLabelText]="'selectGroupsAndMembers' | i18n"
|
||||||
[selectorHelpText]="'userPermissionOverrideHelperDesc' | i18n"
|
[selectorHelpText]="'userPermissionOverrideHelperDesc' | i18n"
|
||||||
[emptySelectionText]="'noMembersOrGroupsAdded' | i18n"
|
[emptySelectionText]="'noMembersOrGroupsAdded' | i18n"
|
||||||
[flexibleCollectionsEnabled]="organization.flexibleCollections"
|
|
||||||
></bit-access-selector>
|
></bit-access-selector>
|
||||||
<bit-access-selector
|
<bit-access-selector
|
||||||
*ngIf="!organization.useGroups"
|
*ngIf="!organization.useGroups"
|
||||||
@ -117,7 +116,6 @@
|
|||||||
[columnHeader]="'memberColumnHeader' | i18n"
|
[columnHeader]="'memberColumnHeader' | i18n"
|
||||||
[selectorLabelText]="'selectMembers' | i18n"
|
[selectorLabelText]="'selectMembers' | i18n"
|
||||||
[emptySelectionText]="'noMembersAdded' | i18n"
|
[emptySelectionText]="'noMembersAdded' | i18n"
|
||||||
[flexibleCollectionsEnabled]="organization.flexibleCollections"
|
|
||||||
></bit-access-selector>
|
></bit-access-selector>
|
||||||
</bit-tab>
|
</bit-tab>
|
||||||
</bit-tab-group>
|
</bit-tab-group>
|
||||||
|
@ -223,7 +223,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
|||||||
(u) => u.userId === this.organization?.userId,
|
(u) => u.userId === this.organization?.userId,
|
||||||
)?.id;
|
)?.id;
|
||||||
const initialSelection: AccessItemValue[] =
|
const initialSelection: AccessItemValue[] =
|
||||||
currentOrgUserId !== undefined && organization.flexibleCollections
|
currentOrgUserId !== undefined
|
||||||
? [
|
? [
|
||||||
{
|
{
|
||||||
id: currentOrgUserId,
|
id: currentOrgUserId,
|
||||||
@ -239,11 +239,7 @@ export class CollectionDialogComponent implements OnInit, OnDestroy {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (flexibleCollectionsV1 && !organization.allowAdminAccessToAllCollectionItems) {
|
||||||
organization.flexibleCollections &&
|
|
||||||
flexibleCollectionsV1 &&
|
|
||||||
!organization.allowAdminAccessToAllCollectionItems
|
|
||||||
) {
|
|
||||||
this.formGroup.controls.access.addValidators(validateCanManagePermission);
|
this.formGroup.controls.access.addValidators(validateCanManagePermission);
|
||||||
} else {
|
} else {
|
||||||
this.formGroup.controls.access.removeValidators(validateCanManagePermission);
|
this.formGroup.controls.access.removeValidators(validateCanManagePermission);
|
||||||
@ -444,8 +440,7 @@ function mapGroupToAccessItemView(group: GroupView, collectionId: string): Acces
|
|||||||
type: AccessItemType.Group,
|
type: AccessItemType.Group,
|
||||||
listName: group.name,
|
listName: group.name,
|
||||||
labelName: group.name,
|
labelName: group.name,
|
||||||
accessAllItems: group.accessAll,
|
readonly: false,
|
||||||
readonly: group.accessAll,
|
|
||||||
readonlyPermission:
|
readonlyPermission:
|
||||||
collectionId != null
|
collectionId != null
|
||||||
? convertToPermission(group.collections.find((gc) => gc.id == collectionId))
|
? convertToPermission(group.collections.find((gc) => gc.id == collectionId))
|
||||||
@ -471,8 +466,7 @@ function mapUserToAccessItemView(
|
|||||||
listName: user.name?.length > 0 ? `${user.name} (${user.email})` : user.email,
|
listName: user.name?.length > 0 ? `${user.name} (${user.email})` : user.email,
|
||||||
labelName: user.name ?? user.email,
|
labelName: user.name ?? user.email,
|
||||||
status: user.status,
|
status: user.status,
|
||||||
accessAllItems: user.accessAll,
|
readonly: false,
|
||||||
readonly: user.accessAll,
|
|
||||||
readonlyPermission:
|
readonlyPermission:
|
||||||
collectionId != null
|
collectionId != null
|
||||||
? convertToPermission(
|
? convertToPermission(
|
||||||
|
@ -86,7 +86,7 @@ export class VaultCollectionRowComponent {
|
|||||||
return this.i18nService.t("canEdit");
|
return this.i18nService.t("canEdit");
|
||||||
}
|
}
|
||||||
if ((this.collection as CollectionAdminView).assigned) {
|
if ((this.collection as CollectionAdminView).assigned) {
|
||||||
const permissionList = getPermissionList(this.organization?.flexibleCollections);
|
const permissionList = getPermissionList();
|
||||||
return this.i18nService.t(
|
return this.i18nService.t(
|
||||||
permissionList.find((p) => p.perm === convertToPermission(this.collection))?.labelId,
|
permissionList.find((p) => p.perm === convertToPermission(this.collection))?.labelId,
|
||||||
);
|
);
|
||||||
|
@ -15,7 +15,6 @@ import { VaultFilter } from "../models/vault-filter.model";
|
|||||||
})
|
})
|
||||||
export class VaultFilterSectionComponent implements OnInit, OnDestroy {
|
export class VaultFilterSectionComponent implements OnInit, OnDestroy {
|
||||||
private destroy$ = new Subject<void>();
|
private destroy$ = new Subject<void>();
|
||||||
protected flexibleCollectionsEnabled: boolean;
|
|
||||||
|
|
||||||
@Input() activeFilter: VaultFilter;
|
@Input() activeFilter: VaultFilter;
|
||||||
@Input() section: VaultFilterSection;
|
@Input() section: VaultFilterSection;
|
||||||
@ -40,12 +39,6 @@ export class VaultFilterSectionComponent implements OnInit, OnDestroy {
|
|||||||
this.section?.data$?.pipe(takeUntil(this.destroy$)).subscribe((data) => {
|
this.section?.data$?.pipe(takeUntil(this.destroy$)).subscribe((data) => {
|
||||||
this.data = data;
|
this.data = data;
|
||||||
});
|
});
|
||||||
this.vaultFilterService
|
|
||||||
.getOrganizationFilter()
|
|
||||||
.pipe(takeUntil(this.destroy$))
|
|
||||||
.subscribe((org) => {
|
|
||||||
this.flexibleCollectionsEnabled = org != null ? org.flexibleCollections : false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
@ -77,10 +70,9 @@ export class VaultFilterSectionComponent implements OnInit, OnDestroy {
|
|||||||
const { organizationId, cipherTypeId, folderId, collectionId, isCollectionSelected } =
|
const { organizationId, cipherTypeId, folderId, collectionId, isCollectionSelected } =
|
||||||
this.activeFilter;
|
this.activeFilter;
|
||||||
|
|
||||||
const collectionStatus = this.flexibleCollectionsEnabled
|
const collectionStatus =
|
||||||
? filterNode?.node.id === "AllCollections" &&
|
filterNode?.node.id === "AllCollections" &&
|
||||||
(isCollectionSelected || collectionId === "AllCollections")
|
(isCollectionSelected || collectionId === "AllCollections");
|
||||||
: collectionId === filterNode?.node.id;
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
organizationId === filterNode?.node.id ||
|
organizationId === filterNode?.node.id ||
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
[selectorLabelText]="'selectGroupsAndMembers' | i18n"
|
[selectorLabelText]="'selectGroupsAndMembers' | i18n"
|
||||||
[selectorHelpText]="'userPermissionOverrideHelperDesc' | i18n"
|
[selectorHelpText]="'userPermissionOverrideHelperDesc' | i18n"
|
||||||
[emptySelectionText]="'noMembersOrGroupsAdded' | i18n"
|
[emptySelectionText]="'noMembersOrGroupsAdded' | i18n"
|
||||||
[flexibleCollectionsEnabled]="flexibleCollectionsEnabled$ | async"
|
|
||||||
></bit-access-selector>
|
></bit-access-selector>
|
||||||
<bit-access-selector
|
<bit-access-selector
|
||||||
*ngIf="!organization?.useGroups"
|
*ngIf="!organization?.useGroups"
|
||||||
@ -27,7 +26,6 @@
|
|||||||
[columnHeader]="'memberColumnHeader' | i18n"
|
[columnHeader]="'memberColumnHeader' | i18n"
|
||||||
[selectorLabelText]="'selectMembers' | i18n"
|
[selectorLabelText]="'selectMembers' | i18n"
|
||||||
[emptySelectionText]="'noMembersAdded' | i18n"
|
[emptySelectionText]="'noMembersAdded' | i18n"
|
||||||
[flexibleCollectionsEnabled]="flexibleCollectionsEnabled$ | async"
|
|
||||||
></bit-access-selector>
|
></bit-access-selector>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
|
||||||
import { Component, Inject, OnDestroy } from "@angular/core";
|
import { Component, Inject, OnDestroy } from "@angular/core";
|
||||||
import { FormBuilder } from "@angular/forms";
|
import { FormBuilder } from "@angular/forms";
|
||||||
import { combineLatest, map, of, Subject, switchMap, takeUntil } from "rxjs";
|
import { combineLatest, of, Subject, switchMap, takeUntil } from "rxjs";
|
||||||
|
|
||||||
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
import { OrganizationUserService } from "@bitwarden/common/admin-console/abstractions/organization-user/organization-user.service";
|
||||||
@ -42,10 +42,6 @@ export enum BulkCollectionsDialogResult {
|
|||||||
standalone: true,
|
standalone: true,
|
||||||
})
|
})
|
||||||
export class BulkCollectionsDialogComponent implements OnDestroy {
|
export class BulkCollectionsDialogComponent implements OnDestroy {
|
||||||
protected flexibleCollectionsEnabled$ = this.organizationService
|
|
||||||
.get$(this.params.organizationId)
|
|
||||||
.pipe(map((o) => o?.flexibleCollections));
|
|
||||||
|
|
||||||
protected readonly PermissionMode = PermissionMode;
|
protected readonly PermissionMode = PermissionMode;
|
||||||
|
|
||||||
protected formGroup = this.formBuilder.group({
|
protected formGroup = this.formBuilder.group({
|
||||||
|
@ -103,11 +103,7 @@ export class VaultFilterComponent extends BaseVaultFilterComponent implements On
|
|||||||
async buildAllFilters(): Promise<VaultFilterList> {
|
async buildAllFilters(): Promise<VaultFilterList> {
|
||||||
const builderFilter = {} as VaultFilterList;
|
const builderFilter = {} as VaultFilterList;
|
||||||
builderFilter.typeFilter = await this.addTypeFilter(["favorites"]);
|
builderFilter.typeFilter = await this.addTypeFilter(["favorites"]);
|
||||||
if (this._organization?.flexibleCollections) {
|
builderFilter.collectionFilter = await this.addCollectionFilter();
|
||||||
builderFilter.collectionFilter = await this.addCollectionFilter();
|
|
||||||
} else {
|
|
||||||
builderFilter.collectionFilter = await super.addCollectionFilter();
|
|
||||||
}
|
|
||||||
builderFilter.trashFilter = await this.addTrashFilter();
|
builderFilter.trashFilter = await this.addTrashFilter();
|
||||||
return builderFilter;
|
return builderFilter;
|
||||||
}
|
}
|
||||||
|
@ -6,10 +6,7 @@
|
|||||||
queryParamsHandling="merge"
|
queryParamsHandling="merge"
|
||||||
>
|
>
|
||||||
{{ organization.name }}
|
{{ organization.name }}
|
||||||
<span *ngIf="!organization.flexibleCollections">
|
<span>
|
||||||
{{ "vault" | i18n | lowercase }}
|
|
||||||
</span>
|
|
||||||
<span *ngIf="organization.flexibleCollections">
|
|
||||||
{{ "collections" | i18n | lowercase }}
|
{{ "collections" | i18n | lowercase }}
|
||||||
</span>
|
</span>
|
||||||
</bit-breadcrumb>
|
</bit-breadcrumb>
|
||||||
|
@ -89,9 +89,7 @@ export class VaultHeaderComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
const headerType = this.organization?.flexibleCollections
|
const headerType = this.i18nService.t("collections").toLowerCase();
|
||||||
? this.i18nService.t("collections").toLowerCase()
|
|
||||||
: this.i18nService.t("vault").toLowerCase();
|
|
||||||
|
|
||||||
if (this.collection != null) {
|
if (this.collection != null) {
|
||||||
return this.collection.node.name;
|
return this.collection.node.name;
|
||||||
|
@ -65,8 +65,8 @@
|
|||||||
[useEvents]="organization?.canAccessEventLogs"
|
[useEvents]="organization?.canAccessEventLogs"
|
||||||
[showAdminActions]="true"
|
[showAdminActions]="true"
|
||||||
(onEvent)="onVaultItemsEvent($event)"
|
(onEvent)="onVaultItemsEvent($event)"
|
||||||
[showBulkEditCollectionAccess]="organization?.flexibleCollections"
|
[showBulkEditCollectionAccess]="true"
|
||||||
[showBulkAddToCollections]="organization?.flexibleCollections"
|
[showBulkAddToCollections]="true"
|
||||||
[viewingOrgVault]="true"
|
[viewingOrgVault]="true"
|
||||||
[flexibleCollectionsV1Enabled]="flexibleCollectionsV1Enabled"
|
[flexibleCollectionsV1Enabled]="flexibleCollectionsV1Enabled"
|
||||||
[addAccessStatus]="addAccessStatus$ | async"
|
[addAccessStatus]="addAccessStatus$ | async"
|
||||||
|
@ -156,7 +156,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
private _flexibleCollectionsV1FlagEnabled: boolean;
|
private _flexibleCollectionsV1FlagEnabled: boolean;
|
||||||
|
|
||||||
protected get flexibleCollectionsV1Enabled(): boolean {
|
protected get flexibleCollectionsV1Enabled(): boolean {
|
||||||
return this._flexibleCollectionsV1FlagEnabled && this.organization?.flexibleCollections;
|
return this._flexibleCollectionsV1FlagEnabled;
|
||||||
}
|
}
|
||||||
protected orgRevokedUsers: OrganizationUserUserDetailsResponse[];
|
protected orgRevokedUsers: OrganizationUserUserDetailsResponse[];
|
||||||
|
|
||||||
|
@ -2794,12 +2794,6 @@
|
|||||||
"userDesc": {
|
"userDesc": {
|
||||||
"message": "Access and add items to assigned collections"
|
"message": "Access and add items to assigned collections"
|
||||||
},
|
},
|
||||||
"manager": {
|
|
||||||
"message": "Manager"
|
|
||||||
},
|
|
||||||
"managerDesc": {
|
|
||||||
"message": "Create, delete, and manage access in assigned collections"
|
|
||||||
},
|
|
||||||
"all": {
|
"all": {
|
||||||
"message": "All"
|
"message": "All"
|
||||||
},
|
},
|
||||||
@ -4576,12 +4570,6 @@
|
|||||||
"permission": {
|
"permission": {
|
||||||
"message": "Permission"
|
"message": "Permission"
|
||||||
},
|
},
|
||||||
"managerPermissions": {
|
|
||||||
"message": "Manager Permissions"
|
|
||||||
},
|
|
||||||
"adminPermissions": {
|
|
||||||
"message": "Admin Permissions"
|
|
||||||
},
|
|
||||||
"accessEventLogs": {
|
"accessEventLogs": {
|
||||||
"message": "Access event logs"
|
"message": "Access event logs"
|
||||||
},
|
},
|
||||||
@ -4606,9 +4594,6 @@
|
|||||||
"deleteAnyCollection": {
|
"deleteAnyCollection": {
|
||||||
"message": "Delete any collection"
|
"message": "Delete any collection"
|
||||||
},
|
},
|
||||||
"manageAssignedCollections": {
|
|
||||||
"message": "Manage assigned collections"
|
|
||||||
},
|
|
||||||
"editAssignedCollections": {
|
"editAssignedCollections": {
|
||||||
"message": "Edit assigned collections"
|
"message": "Edit assigned collections"
|
||||||
},
|
},
|
||||||
@ -6669,12 +6654,6 @@
|
|||||||
"restrictedCollectionAssignmentDesc": {
|
"restrictedCollectionAssignmentDesc": {
|
||||||
"message": "You can only assign collections you manage."
|
"message": "You can only assign collections you manage."
|
||||||
},
|
},
|
||||||
"accessAllCollectionsDesc": {
|
|
||||||
"message": "Grant access to all current and future collections."
|
|
||||||
},
|
|
||||||
"accessAllCollectionsHelp": {
|
|
||||||
"message": "If checked, this will replace all other collection permissions."
|
|
||||||
},
|
|
||||||
"selectMembers": {
|
"selectMembers": {
|
||||||
"message": "Select members"
|
"message": "Select members"
|
||||||
},
|
},
|
||||||
@ -6717,12 +6696,6 @@
|
|||||||
"group": {
|
"group": {
|
||||||
"message": "Group"
|
"message": "Group"
|
||||||
},
|
},
|
||||||
"groupAccessAll": {
|
|
||||||
"message": "This group can access and modify all items."
|
|
||||||
},
|
|
||||||
"memberAccessAll": {
|
|
||||||
"message": "This member can access and modify all items."
|
|
||||||
},
|
|
||||||
"domainVerification": {
|
"domainVerification": {
|
||||||
"message": "Domain verification"
|
"message": "Domain verification"
|
||||||
},
|
},
|
||||||
|
@ -20,8 +20,6 @@ export class UserTypePipe implements PipeTransform {
|
|||||||
return this.i18nService.t("admin");
|
return this.i18nService.t("admin");
|
||||||
case OrganizationUserType.User:
|
case OrganizationUserType.User:
|
||||||
return this.i18nService.t("user");
|
return this.i18nService.t("user");
|
||||||
case OrganizationUserType.Manager:
|
|
||||||
return this.i18nService.t("manager");
|
|
||||||
case OrganizationUserType.Custom:
|
case OrganizationUserType.Custom:
|
||||||
return this.i18nService.t("custom");
|
return this.i18nService.t("custom");
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import { SelectionReadOnlyRequest } from "../../../models/request/selection-read
|
|||||||
export class OrganizationUserInviteRequest {
|
export class OrganizationUserInviteRequest {
|
||||||
emails: string[] = [];
|
emails: string[] = [];
|
||||||
type: OrganizationUserType;
|
type: OrganizationUserType;
|
||||||
accessAll: boolean;
|
|
||||||
accessSecretsManager: boolean;
|
accessSecretsManager: boolean;
|
||||||
collections: SelectionReadOnlyRequest[] = [];
|
collections: SelectionReadOnlyRequest[] = [];
|
||||||
groups: string[];
|
groups: string[];
|
||||||
|
@ -4,7 +4,6 @@ import { SelectionReadOnlyRequest } from "../../../models/request/selection-read
|
|||||||
|
|
||||||
export class OrganizationUserUpdateRequest {
|
export class OrganizationUserUpdateRequest {
|
||||||
type: OrganizationUserType;
|
type: OrganizationUserType;
|
||||||
accessAll: boolean;
|
|
||||||
accessSecretsManager: boolean;
|
accessSecretsManager: boolean;
|
||||||
collections: SelectionReadOnlyRequest[] = [];
|
collections: SelectionReadOnlyRequest[] = [];
|
||||||
groups: string[] = [];
|
groups: string[] = [];
|
||||||
|
@ -10,11 +10,6 @@ export class OrganizationUserResponse extends BaseResponse {
|
|||||||
type: OrganizationUserType;
|
type: OrganizationUserType;
|
||||||
status: OrganizationUserStatusType;
|
status: OrganizationUserStatusType;
|
||||||
externalId: string;
|
externalId: string;
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* To be removed after Flexible Collections.
|
|
||||||
**/
|
|
||||||
accessAll: boolean;
|
|
||||||
accessSecretsManager: boolean;
|
accessSecretsManager: boolean;
|
||||||
permissions: PermissionsApi;
|
permissions: PermissionsApi;
|
||||||
resetPasswordEnrolled: boolean;
|
resetPasswordEnrolled: boolean;
|
||||||
@ -30,7 +25,6 @@ export class OrganizationUserResponse extends BaseResponse {
|
|||||||
this.status = this.getResponseProperty("Status");
|
this.status = this.getResponseProperty("Status");
|
||||||
this.permissions = new PermissionsApi(this.getResponseProperty("Permissions"));
|
this.permissions = new PermissionsApi(this.getResponseProperty("Permissions"));
|
||||||
this.externalId = this.getResponseProperty("ExternalId");
|
this.externalId = this.getResponseProperty("ExternalId");
|
||||||
this.accessAll = this.getResponseProperty("AccessAll");
|
|
||||||
this.accessSecretsManager = this.getResponseProperty("AccessSecretsManager");
|
this.accessSecretsManager = this.getResponseProperty("AccessSecretsManager");
|
||||||
this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
|
this.resetPasswordEnrolled = this.getResponseProperty("ResetPasswordEnrolled");
|
||||||
this.hasMasterPassword = this.getResponseProperty("HasMasterPassword");
|
this.hasMasterPassword = this.getResponseProperty("HasMasterPassword");
|
||||||
|
@ -7,7 +7,7 @@ import { OrganizationData } from "../../models/data/organization.data";
|
|||||||
import { Organization } from "../../models/domain/organization";
|
import { Organization } from "../../models/domain/organization";
|
||||||
|
|
||||||
export function canAccessVaultTab(org: Organization): boolean {
|
export function canAccessVaultTab(org: Organization): boolean {
|
||||||
return org.canViewAssignedCollections || org.canViewAllCollections;
|
return org.canViewAllCollections;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canAccessSettingsTab(org: Organization): boolean {
|
export function canAccessSettingsTab(org: Organization): boolean {
|
||||||
@ -77,10 +77,7 @@ export function canAccessImportExport(i18nService: I18nService) {
|
|||||||
export function canAccessImport(i18nService: I18nService) {
|
export function canAccessImport(i18nService: I18nService) {
|
||||||
return map<Organization[], Organization[]>((orgs) =>
|
return map<Organization[], Organization[]>((orgs) =>
|
||||||
orgs
|
orgs
|
||||||
.filter(
|
.filter((org) => org.canAccessImportExport || org.canCreateNewCollections)
|
||||||
(org) =>
|
|
||||||
org.canAccessImportExport || (org.canCreateNewCollections && org.flexibleCollections),
|
|
||||||
)
|
|
||||||
.sort(Utils.getSortFunction(i18nService, "name")),
|
.sort(Utils.getSortFunction(i18nService, "name")),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -142,16 +142,6 @@ export class Organization {
|
|||||||
return this.enabled && this.status === OrganizationUserStatusType.Confirmed;
|
return this.enabled && this.status === OrganizationUserStatusType.Confirmed;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Whether a user has Manager permissions or greater
|
|
||||||
*
|
|
||||||
* @deprecated
|
|
||||||
* This is deprecated with the introduction of Flexible Collections.
|
|
||||||
*/
|
|
||||||
get isManager() {
|
|
||||||
return this.type === OrganizationUserType.Manager || this.isAdmin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Whether a user has Admin permissions or greater
|
* Whether a user has Admin permissions or greater
|
||||||
*/
|
*/
|
||||||
@ -179,19 +169,13 @@ export class Organization {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get canCreateNewCollections() {
|
get canCreateNewCollections() {
|
||||||
if (this.flexibleCollections) {
|
return (
|
||||||
return (
|
!this.limitCollectionCreationDeletion || this.isAdmin || this.permissions.createNewCollections
|
||||||
!this.limitCollectionCreationDeletion ||
|
);
|
||||||
this.isAdmin ||
|
|
||||||
this.permissions.createNewCollections
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return this.isManager || this.permissions.createNewCollections;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
canEditAnyCollection(flexibleCollectionsV1Enabled: boolean) {
|
canEditAnyCollection(flexibleCollectionsV1Enabled: boolean) {
|
||||||
if (!this.flexibleCollections || !flexibleCollectionsV1Enabled) {
|
if (!flexibleCollectionsV1Enabled) {
|
||||||
// Pre-Flexible Collections v1 logic
|
// Pre-Flexible Collections v1 logic
|
||||||
return this.isAdmin || this.permissions.editAnyCollection;
|
return this.isAdmin || this.permissions.editAnyCollection;
|
||||||
}
|
}
|
||||||
@ -221,8 +205,8 @@ export class Organization {
|
|||||||
flexibleCollectionsV1Enabled: boolean,
|
flexibleCollectionsV1Enabled: boolean,
|
||||||
restrictProviderAccessFlagEnabled: boolean,
|
restrictProviderAccessFlagEnabled: boolean,
|
||||||
) {
|
) {
|
||||||
// Before Flexible Collections, any admin or anyone with editAnyCollection permission could edit all ciphers
|
// Before Flexible Collections V1, any admin or anyone with editAnyCollection permission could edit all ciphers
|
||||||
if (!this.flexibleCollections || !flexibleCollectionsV1Enabled || !this.flexibleCollections) {
|
if (!flexibleCollectionsV1Enabled) {
|
||||||
return this.isAdmin || this.permissions.editAnyCollection;
|
return this.isAdmin || this.permissions.editAnyCollection;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -269,33 +253,6 @@ export class Organization {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* This is deprecated with the introduction of Flexible Collections.
|
|
||||||
* This will always return false if FlexibleCollections flag is on.
|
|
||||||
*/
|
|
||||||
get canEditAssignedCollections() {
|
|
||||||
return this.isManager || this.permissions.editAssignedCollections;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* This is deprecated with the introduction of Flexible Collections.
|
|
||||||
* This will always return false if FlexibleCollections flag is on.
|
|
||||||
*/
|
|
||||||
get canDeleteAssignedCollections() {
|
|
||||||
return this.isManager || this.permissions.deleteAssignedCollections;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated
|
|
||||||
* This is deprecated with the introduction of Flexible Collections.
|
|
||||||
* This will always return false if FlexibleCollections flag is on.
|
|
||||||
*/
|
|
||||||
get canViewAssignedCollections() {
|
|
||||||
return this.canDeleteAssignedCollections || this.canEditAssignedCollections;
|
|
||||||
}
|
|
||||||
|
|
||||||
get canManageGroups() {
|
get canManageGroups() {
|
||||||
return (this.isAdmin || this.permissions.manageGroups) && this.useGroups;
|
return (this.isAdmin || this.permissions.manageGroups) && this.useGroups;
|
||||||
}
|
}
|
||||||
|
@ -49,15 +49,11 @@ export class CollectionView implements View, ITreeNodeObject {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (org?.flexibleCollections) {
|
return (
|
||||||
return (
|
org?.canEditAllCiphers(v1FlexibleCollections, restrictProviderAccess) ||
|
||||||
org?.canEditAllCiphers(v1FlexibleCollections, restrictProviderAccess) ||
|
this.manage ||
|
||||||
this.manage ||
|
(this.assigned && !this.readOnly)
|
||||||
(this.assigned && !this.readOnly)
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return org?.canEditAnyCollection(false) || (org?.canEditAssignedCollections && this.assigned);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -256,17 +256,14 @@ export class ImportComponent implements OnInit, OnDestroy {
|
|||||||
if (!this._importBlockedByPolicy) {
|
if (!this._importBlockedByPolicy) {
|
||||||
this.formGroup.controls.targetSelector.enable();
|
this.formGroup.controls.targetSelector.enable();
|
||||||
}
|
}
|
||||||
const flexCollectionEnabled =
|
|
||||||
organizations.find((x) => x.id == this.organizationId)?.flexibleCollections ?? false;
|
|
||||||
if (value) {
|
if (value) {
|
||||||
this.collections$ = Utils.asyncToObservable(() =>
|
this.collections$ = Utils.asyncToObservable(() =>
|
||||||
this.collectionService
|
this.collectionService
|
||||||
.getAllDecrypted()
|
.getAllDecrypted()
|
||||||
.then((decryptedCollections) =>
|
.then((decryptedCollections) =>
|
||||||
decryptedCollections
|
decryptedCollections
|
||||||
.filter(
|
.filter((c2) => c2.organizationId === value && c2.manage)
|
||||||
(c2) => c2.organizationId === value && (!flexCollectionEnabled || c2.manage),
|
|
||||||
)
|
|
||||||
.sort(Utils.getSortFunction(this.i18nService, "name")),
|
.sort(Utils.getSortFunction(this.i18nService, "name")),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -167,11 +167,7 @@ export class ExportComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
||||||
map((orgs) =>
|
map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name"))),
|
||||||
orgs
|
|
||||||
.filter((org) => org.flexibleCollections)
|
|
||||||
.sort(Utils.getSortFunction(this.i18nService, "name")),
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
this.exportForm.controls.vaultSelector.valueChanges
|
this.exportForm.controls.vaultSelector.valueChanges
|
||||||
|
Loading…
Reference in New Issue
Block a user