mirror of
https://github.com/bitwarden/browser
synced 2025-12-19 01:33:33 +00:00
[AC-1139] Checking if FC feature flag is enabled when using canDeleteAssignedCollections or canViewAssignedCollections
This commit is contained in:
@@ -1,11 +1,13 @@
|
|||||||
import { Component, Input, OnInit } from "@angular/core";
|
import { Component, Input, OnInit } from "@angular/core";
|
||||||
import { map, Observable } from "rxjs";
|
import { combineLatest, map, Observable } from "rxjs";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
canAccessAdmin,
|
canAccessAdmin,
|
||||||
OrganizationService,
|
OrganizationService,
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
import { Utils } from "@bitwarden/common/platform/misc/utils";
|
||||||
|
|
||||||
@@ -14,7 +16,11 @@ import { Utils } from "@bitwarden/common/platform/misc/utils";
|
|||||||
templateUrl: "organization-switcher.component.html",
|
templateUrl: "organization-switcher.component.html",
|
||||||
})
|
})
|
||||||
export class OrganizationSwitcherComponent implements OnInit {
|
export class OrganizationSwitcherComponent implements OnInit {
|
||||||
constructor(private organizationService: OrganizationService, private i18nService: I18nService) {}
|
constructor(
|
||||||
|
private organizationService: OrganizationService,
|
||||||
|
private i18nService: I18nService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
|
) {}
|
||||||
|
|
||||||
@Input() activeOrganization: Organization = null;
|
@Input() activeOrganization: Organization = null;
|
||||||
organizations$: Observable<Organization[]>;
|
organizations$: Observable<Organization[]>;
|
||||||
@@ -22,9 +28,14 @@ export class OrganizationSwitcherComponent implements OnInit {
|
|||||||
loaded = false;
|
loaded = false;
|
||||||
|
|
||||||
async ngOnInit() {
|
async ngOnInit() {
|
||||||
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
this.organizations$ = combineLatest([
|
||||||
canAccessAdmin(this.i18nService),
|
this.organizationService.memberOrganizations$,
|
||||||
map((orgs) => orgs.sort(Utils.getSortFunction(this.i18nService, "name")))
|
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollections, false),
|
||||||
|
]).pipe(
|
||||||
|
map(([orgs, flexibleCollectionsEnabled]) => {
|
||||||
|
const canAccess = canAccessAdmin(this.i18nService, flexibleCollectionsEnabled);
|
||||||
|
return canAccess ? orgs.sort(Utils.getSortFunction(this.i18nService, "name")) : [];
|
||||||
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.loaded = true;
|
this.loaded = true;
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { mock, MockProxy } from "jest-mock-extended";
|
|||||||
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 { OrganizationUserType } from "@bitwarden/common/admin-console/enums";
|
import { OrganizationUserType } from "@bitwarden/common/admin-console/enums";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||||
@@ -52,7 +53,8 @@ describe("Organization Permissions Guard", () => {
|
|||||||
organizationService,
|
organizationService,
|
||||||
mock<PlatformUtilsService>(),
|
mock<PlatformUtilsService>(),
|
||||||
mock<I18nService>(),
|
mock<I18nService>(),
|
||||||
mock<SyncService>()
|
mock<SyncService>(),
|
||||||
|
mock<ConfigServiceAbstraction>()
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import {
|
|||||||
OrganizationService,
|
OrganizationService,
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
import { SyncService } from "@bitwarden/common/vault/abstractions/sync/sync.service.abstraction";
|
||||||
@@ -19,7 +21,8 @@ export class OrganizationPermissionsGuard implements CanActivate {
|
|||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private syncService: SyncService
|
private syncService: SyncService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||||
@@ -42,9 +45,17 @@ export class OrganizationPermissionsGuard implements CanActivate {
|
|||||||
return this.router.createUrlTree(["/"]);
|
return this.router.createUrlTree(["/"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
const permissionsCallback: (organization: Organization) => boolean =
|
const flexibleCollectionsEnabled = await this.configService.getFeatureFlag(
|
||||||
route.data?.organizationPermissions;
|
FeatureFlag.FlexibleCollections,
|
||||||
const hasPermissions = permissionsCallback == null || permissionsCallback(org);
|
false
|
||||||
|
);
|
||||||
|
|
||||||
|
const permissionsCallback: (
|
||||||
|
organization: Organization,
|
||||||
|
flexibleCollectionsEnabled: boolean
|
||||||
|
) => boolean = route.data?.organizationPermissions;
|
||||||
|
const hasPermissions =
|
||||||
|
permissionsCallback == null || permissionsCallback(org, flexibleCollectionsEnabled);
|
||||||
|
|
||||||
if (!hasPermissions) {
|
if (!hasPermissions) {
|
||||||
// Handle linkable ciphers for organizations the user only has view access to
|
// Handle linkable ciphers for organizations the user only has view access to
|
||||||
@@ -60,7 +71,7 @@ export class OrganizationPermissionsGuard implements CanActivate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.platformUtilsService.showToast("error", null, this.i18nService.t("accessDenied"));
|
this.platformUtilsService.showToast("error", null, this.i18nService.t("accessDenied"));
|
||||||
return canAccessOrgAdmin(org)
|
return canAccessOrgAdmin(org, flexibleCollectionsEnabled)
|
||||||
? this.router.createUrlTree(["/organizations", org.id])
|
? this.router.createUrlTree(["/organizations", org.id])
|
||||||
: this.router.createUrlTree(["/"]);
|
: this.router.createUrlTree(["/"]);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,15 +5,25 @@ import {
|
|||||||
canAccessOrgAdmin,
|
canAccessOrgAdmin,
|
||||||
OrganizationService,
|
OrganizationService,
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: "root",
|
providedIn: "root",
|
||||||
})
|
})
|
||||||
export class OrganizationRedirectGuard implements CanActivate {
|
export class OrganizationRedirectGuard implements CanActivate {
|
||||||
constructor(private router: Router, private organizationService: OrganizationService) {}
|
constructor(
|
||||||
|
private router: Router,
|
||||||
|
private organizationService: OrganizationService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
|
) {}
|
||||||
|
|
||||||
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
async canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
|
||||||
const org = this.organizationService.get(route.params.organizationId);
|
const org = this.organizationService.get(route.params.organizationId);
|
||||||
|
const flexibleCollectionsEnabled = await this.configService.getFeatureFlag(
|
||||||
|
FeatureFlag.FlexibleCollections,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
|
||||||
const customRedirect = route.data?.autoRedirectCallback;
|
const customRedirect = route.data?.autoRedirectCallback;
|
||||||
if (customRedirect) {
|
if (customRedirect) {
|
||||||
@@ -24,7 +34,7 @@ export class OrganizationRedirectGuard implements CanActivate {
|
|||||||
return this.router.createUrlTree([state.url, ...redirectPath]);
|
return this.router.createUrlTree([state.url, ...redirectPath]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canAccessOrgAdmin(org)) {
|
if (canAccessOrgAdmin(org, flexibleCollectionsEnabled)) {
|
||||||
return this.router.createUrlTree(["/organizations", org.id]);
|
return this.router.createUrlTree(["/organizations", org.id]);
|
||||||
}
|
}
|
||||||
return this.router.createUrlTree(["/"]);
|
return this.router.createUrlTree(["/"]);
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import {
|
|||||||
OrganizationService,
|
OrganizationService,
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: "app-organization-layout",
|
selector: "app-organization-layout",
|
||||||
@@ -22,12 +24,21 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
organization$: Observable<Organization>;
|
organization$: Observable<Organization>;
|
||||||
|
|
||||||
private _destroy = new Subject<void>();
|
private _destroy = new Subject<void>();
|
||||||
|
private flexibleCollectionsEnabled: boolean;
|
||||||
|
|
||||||
constructor(private route: ActivatedRoute, private organizationService: OrganizationService) {}
|
constructor(
|
||||||
|
private route: ActivatedRoute,
|
||||||
|
private organizationService: OrganizationService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
async ngOnInit() {
|
||||||
document.body.classList.remove("layout_frontend");
|
document.body.classList.remove("layout_frontend");
|
||||||
|
|
||||||
|
this.flexibleCollectionsEnabled = await this.configService.getFeatureFlag(
|
||||||
|
FeatureFlag.FlexibleCollections
|
||||||
|
);
|
||||||
|
|
||||||
this.organization$ = this.route.params
|
this.organization$ = this.route.params
|
||||||
.pipe(takeUntil(this._destroy))
|
.pipe(takeUntil(this._destroy))
|
||||||
.pipe<string>(map((p) => p.organizationId))
|
.pipe<string>(map((p) => p.organizationId))
|
||||||
@@ -46,7 +57,7 @@ export class OrganizationLayoutComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
canShowVaultTab(organization: Organization): boolean {
|
canShowVaultTab(organization: Organization): boolean {
|
||||||
return canAccessVaultTab(organization);
|
return canAccessVaultTab(organization, this.flexibleCollectionsEnabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
canShowSettingsTab(organization: Organization): boolean {
|
canShowSettingsTab(organization: Organization): boolean {
|
||||||
|
|||||||
@@ -78,8 +78,11 @@ const routes: Routes = [
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
function getOrganizationRoute(organization: Organization): string {
|
function getOrganizationRoute(
|
||||||
if (canAccessVaultTab(organization)) {
|
organization: Organization,
|
||||||
|
flexibleCollectionsEnabled: boolean
|
||||||
|
): string {
|
||||||
|
if (canAccessVaultTab(organization, flexibleCollectionsEnabled)) {
|
||||||
return "vault";
|
return "vault";
|
||||||
}
|
}
|
||||||
if (canAccessMembersTab(organization)) {
|
if (canAccessMembersTab(organization)) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import { Component, OnInit } from "@angular/core";
|
import { Component, OnInit } from "@angular/core";
|
||||||
import { map, Observable } from "rxjs";
|
import { combineLatest, map, Observable } from "rxjs";
|
||||||
|
|
||||||
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service";
|
import { VaultTimeoutSettingsService } from "@bitwarden/common/abstractions/vault-timeout/vault-timeout-settings.service";
|
||||||
import {
|
import {
|
||||||
@@ -9,8 +9,10 @@ import {
|
|||||||
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
import { ProviderService } from "@bitwarden/common/admin-console/abstractions/provider.service";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
import { TokenService } from "@bitwarden/common/auth/abstractions/token.service";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
import { VaultTimeoutAction } from "@bitwarden/common/enums/vault-timeout-action.enum";
|
||||||
import { Provider } from "@bitwarden/common/models/domain/provider";
|
import { Provider } from "@bitwarden/common/models/domain/provider";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
@@ -38,7 +40,8 @@ export class NavbarComponent implements OnInit {
|
|||||||
private syncService: SyncService,
|
private syncService: SyncService,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
private vaultTimeoutSettingsService: VaultTimeoutSettingsService,
|
||||||
private i18nService: I18nService
|
private i18nService: I18nService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
) {
|
) {
|
||||||
this.selfHosted = this.platformUtilsService.isSelfHost();
|
this.selfHosted = this.platformUtilsService.isSelfHost();
|
||||||
}
|
}
|
||||||
@@ -57,8 +60,14 @@ export class NavbarComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
this.providers = await this.providerService.getAll();
|
this.providers = await this.providerService.getAll();
|
||||||
|
|
||||||
this.organizations$ = this.organizationService.memberOrganizations$.pipe(
|
this.organizations$ = combineLatest([
|
||||||
canAccessAdmin(this.i18nService)
|
this.organizationService.memberOrganizations$,
|
||||||
|
this.configService.getFeatureFlag$(FeatureFlag.FlexibleCollections, false),
|
||||||
|
]).pipe(
|
||||||
|
map(([organizations, featureFlag]) => {
|
||||||
|
const canAccess = canAccessAdmin(this.i18nService, featureFlag);
|
||||||
|
return canAccess ? organizations : [];
|
||||||
|
})
|
||||||
);
|
);
|
||||||
this.canLock$ = this.vaultTimeoutSettingsService
|
this.canLock$ = this.vaultTimeoutSettingsService
|
||||||
.availableVaultTimeoutActions$()
|
.availableVaultTimeoutActions$()
|
||||||
|
|||||||
@@ -6,6 +6,8 @@ import {
|
|||||||
OrganizationService,
|
OrganizationService,
|
||||||
canAccessVaultTab,
|
canAccessVaultTab,
|
||||||
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
} from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { ImportComponent } from "@bitwarden/importer/ui";
|
import { ImportComponent } from "@bitwarden/importer/ui";
|
||||||
|
|
||||||
import { SharedModule } from "../../shared";
|
import { SharedModule } from "../../shared";
|
||||||
@@ -20,14 +22,20 @@ export class ImportWebComponent implements OnInit {
|
|||||||
protected loading = false;
|
protected loading = false;
|
||||||
protected disabled = false;
|
protected disabled = false;
|
||||||
|
|
||||||
|
private flexibleCollectionsEnabled: boolean;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private route: ActivatedRoute,
|
private route: ActivatedRoute,
|
||||||
private organizationService: OrganizationService,
|
private organizationService: OrganizationService,
|
||||||
private router: Router
|
private router: Router,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit(): void {
|
async ngOnInit() {
|
||||||
this.routeOrgId = this.route.snapshot.paramMap.get("organizationId");
|
this.routeOrgId = this.route.snapshot.paramMap.get("organizationId");
|
||||||
|
this.flexibleCollectionsEnabled = await this.configService.getFeatureFlag(
|
||||||
|
FeatureFlag.FlexibleCollections
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -44,7 +52,7 @@ export class ImportWebComponent implements OnInit {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (canAccessVaultTab(organization)) {
|
if (canAccessVaultTab(organization, this.flexibleCollectionsEnabled)) {
|
||||||
await this.router.navigate(["organizations", organizationId, "vault"]);
|
await this.router.navigate(["organizations", organizationId, "vault"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -109,7 +109,10 @@
|
|||||||
{{ "cancel" | i18n }}
|
{{ "cancel" | i18n }}
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
*ngIf="editMode && organization?.canDeleteAssignedCollections"
|
*ngIf="
|
||||||
|
editMode &&
|
||||||
|
((flexibleCollectionsEnabled$ | async) || organization?.canDeleteAssignedCollections)
|
||||||
|
"
|
||||||
type="button"
|
type="button"
|
||||||
bitIconButton="bwi-trash"
|
bitIconButton="bwi-trash"
|
||||||
buttonType="danger"
|
buttonType="danger"
|
||||||
|
|||||||
@@ -3,6 +3,8 @@ import { Component, Inject } from "@angular/core";
|
|||||||
|
|
||||||
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
import { ApiService } from "@bitwarden/common/abstractions/api.service";
|
||||||
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
|
||||||
|
import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
|
||||||
|
import { ConfigServiceAbstraction } from "@bitwarden/common/platform/abstractions/config/config.service.abstraction";
|
||||||
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
|
||||||
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
|
||||||
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
|
||||||
@@ -58,7 +60,8 @@ export class BulkDeleteDialogComponent {
|
|||||||
private platformUtilsService: PlatformUtilsService,
|
private platformUtilsService: PlatformUtilsService,
|
||||||
private i18nService: I18nService,
|
private i18nService: I18nService,
|
||||||
private apiService: ApiService,
|
private apiService: ApiService,
|
||||||
private collectionService: CollectionService
|
private collectionService: CollectionService,
|
||||||
|
private configService: ConfigServiceAbstraction
|
||||||
) {
|
) {
|
||||||
this.cipherIds = params.cipherIds ?? [];
|
this.cipherIds = params.cipherIds ?? [];
|
||||||
this.collectionIds = params.collectionIds ?? [];
|
this.collectionIds = params.collectionIds ?? [];
|
||||||
@@ -125,10 +128,14 @@ export class BulkDeleteDialogComponent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async deleteCollections(): Promise<any> {
|
private async deleteCollections(): Promise<any> {
|
||||||
|
const flexibleCollectionsEnabled = await this.configService.getFeatureFlag(
|
||||||
|
FeatureFlag.FlexibleCollections,
|
||||||
|
false
|
||||||
|
);
|
||||||
// From org vault
|
// From org vault
|
||||||
if (this.organization) {
|
if (this.organization) {
|
||||||
if (
|
if (
|
||||||
!this.organization.canDeleteAssignedCollections &&
|
(flexibleCollectionsEnabled || !this.organization.canDeleteAssignedCollections) &&
|
||||||
!this.organization.canDeleteAnyCollection
|
!this.organization.canDeleteAnyCollection
|
||||||
) {
|
) {
|
||||||
this.platformUtilsService.showToast(
|
this.platformUtilsService.showToast(
|
||||||
@@ -143,7 +150,10 @@ export class BulkDeleteDialogComponent {
|
|||||||
} else if (this.organizations && this.collections) {
|
} else if (this.organizations && this.collections) {
|
||||||
const deletePromises: Promise<any>[] = [];
|
const deletePromises: Promise<any>[] = [];
|
||||||
for (const organization of this.organizations) {
|
for (const organization of this.organizations) {
|
||||||
if (!organization.canDeleteAssignedCollections && !organization.canDeleteAnyCollection) {
|
if (
|
||||||
|
(flexibleCollectionsEnabled || !this.organization.canDeleteAssignedCollections) &&
|
||||||
|
!organization.canDeleteAnyCollection
|
||||||
|
) {
|
||||||
this.platformUtilsService.showToast(
|
this.platformUtilsService.showToast(
|
||||||
"error",
|
"error",
|
||||||
this.i18nService.t("errorOccurred"),
|
this.i18nService.t("errorOccurred"),
|
||||||
|
|||||||
@@ -687,7 +687,14 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
|
|
||||||
async deleteCollection(collection: CollectionView): Promise<void> {
|
async deleteCollection(collection: CollectionView): Promise<void> {
|
||||||
const organization = this.organizationService.get(collection.organizationId);
|
const organization = this.organizationService.get(collection.organizationId);
|
||||||
if (!organization.canDeleteAssignedCollections && !organization.canDeleteAnyCollection) {
|
const flexibleCollectionsEnabled = await this.configService.getFeatureFlag(
|
||||||
|
FeatureFlag.FlexibleCollections,
|
||||||
|
false
|
||||||
|
);
|
||||||
|
if (
|
||||||
|
(flexibleCollectionsEnabled || !organization.canDeleteAssignedCollections) &&
|
||||||
|
!organization.canDeleteAnyCollection
|
||||||
|
) {
|
||||||
this.platformUtilsService.showToast(
|
this.platformUtilsService.showToast(
|
||||||
"error",
|
"error",
|
||||||
this.i18nService.t("errorOccurred"),
|
this.i18nService.t("errorOccurred"),
|
||||||
|
|||||||
@@ -132,6 +132,7 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
FeatureFlag.BulkCollectionAccess,
|
FeatureFlag.BulkCollectionAccess,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
protected flexibleCollectionsEnabled: boolean;
|
||||||
|
|
||||||
private searchText$ = new Subject<string>();
|
private searchText$ = new Subject<string>();
|
||||||
private refresh$ = new BehaviorSubject<void>(null);
|
private refresh$ = new BehaviorSubject<void>(null);
|
||||||
@@ -750,8 +751,12 @@ export class VaultComponent implements OnInit, OnDestroy {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async deleteCollection(collection: CollectionView): Promise<void> {
|
async deleteCollection(collection: CollectionView): Promise<void> {
|
||||||
|
const flexibleCollectionsEnabled = await this.configService.getFeatureFlag(
|
||||||
|
FeatureFlag.FlexibleCollections,
|
||||||
|
false
|
||||||
|
);
|
||||||
if (
|
if (
|
||||||
!this.organization.canDeleteAssignedCollections &&
|
(flexibleCollectionsEnabled || !this.organization.canDeleteAssignedCollections) &&
|
||||||
!this.organization.canDeleteAnyCollection
|
!this.organization.canDeleteAnyCollection
|
||||||
) {
|
) {
|
||||||
this.platformUtilsService.showToast(
|
this.platformUtilsService.showToast(
|
||||||
|
|||||||
@@ -5,8 +5,12 @@ import { Utils } from "../../../platform/misc/utils";
|
|||||||
import { OrganizationData } from "../../models/data/organization.data";
|
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, flexibleCollectionsEnabled: boolean): boolean {
|
||||||
return org.canViewAssignedCollections || org.canViewAllCollections;
|
if (flexibleCollectionsEnabled) {
|
||||||
|
return org.canViewAllCollections;
|
||||||
|
} else {
|
||||||
|
return org.canViewAssignedCollections || org.canViewAllCollections;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canAccessSettingsTab(org: Organization): boolean {
|
export function canAccessSettingsTab(org: Organization): boolean {
|
||||||
@@ -36,14 +40,14 @@ export function canAccessBillingTab(org: Organization): boolean {
|
|||||||
return org.isOwner;
|
return org.isOwner;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canAccessOrgAdmin(org: Organization): boolean {
|
export function canAccessOrgAdmin(org: Organization, flexibleCollectionsEnabled: boolean): boolean {
|
||||||
return (
|
return (
|
||||||
canAccessMembersTab(org) ||
|
canAccessMembersTab(org) ||
|
||||||
canAccessGroupsTab(org) ||
|
canAccessGroupsTab(org) ||
|
||||||
canAccessReportingTab(org) ||
|
canAccessReportingTab(org) ||
|
||||||
canAccessBillingTab(org) ||
|
canAccessBillingTab(org) ||
|
||||||
canAccessSettingsTab(org) ||
|
canAccessSettingsTab(org) ||
|
||||||
canAccessVaultTab(org)
|
canAccessVaultTab(org, flexibleCollectionsEnabled)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,9 +55,11 @@ export function getOrganizationById(id: string) {
|
|||||||
return map<Organization[], Organization | undefined>((orgs) => orgs.find((o) => o.id === id));
|
return map<Organization[], Organization | undefined>((orgs) => orgs.find((o) => o.id === id));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function canAccessAdmin(i18nService: I18nService) {
|
export function canAccessAdmin(i18nService: I18nService, flexibleCollectionsEnabled: boolean) {
|
||||||
return map<Organization[], Organization[]>((orgs) =>
|
return map<Organization[], Organization[]>((orgs) =>
|
||||||
orgs.filter(canAccessOrgAdmin).sort(Utils.getSortFunction(i18nService, "name"))
|
orgs
|
||||||
|
.filter((org) => canAccessOrgAdmin(org, flexibleCollectionsEnabled))
|
||||||
|
.sort(Utils.getSortFunction(i18nService, "name"))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user