diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index 9eace676f4f..9665d40b07e 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -100,12 +100,19 @@ apps/desktop/src/services/native-message-handler.service.ts @bitwarden/team-auto
## Component Library ##
.storybook @bitwarden/team-design-system
libs/components @bitwarden/team-design-system
-apps/browser/src/platform/popup/layout @bitwarden/team-design-system
-apps/web/src/app/layouts @bitwarden/team-design-system
+apps/browser/src/platform/popup/layout @bitwarden/team-design-system
+apps/web/src/app/layouts @bitwarden/team-design-system
## Desktop native module ##
apps/desktop/desktop_native @bitwarden/team-platform-dev
+## Key management team files ##
+apps/desktop/src/key-management @bitwarden/team-key-management-dev
+apps/web/src/key-management @bitwarden/team-key-management-dev
+apps/browser/src/key-management @bitwarden/team-key-management-dev
+apps/cli/src/key-management @bitwarden/team-key-management-dev
+libs/common/src/key-management @bitwarden/team-key-management-dev
+
## DevOps team files ##
/.github/workflows @bitwarden/dept-devops
diff --git a/apps/browser/src/popup/app-routing.module.ts b/apps/browser/src/popup/app-routing.module.ts
index 50f1aef6c00..f715d38422d 100644
--- a/apps/browser/src/popup/app-routing.module.ts
+++ b/apps/browser/src/popup/app-routing.module.ts
@@ -10,6 +10,7 @@ import {
} from "@bitwarden/angular/auth/guards";
import { canAccessFeature } from "@bitwarden/angular/platform/guard/feature-flag.guard";
import { generatorSwap } from "@bitwarden/angular/tools/generator/generator-swap";
+import { extensionRefreshRedirect } from "@bitwarden/angular/utils/extension-refresh-redirect";
import { extensionRefreshSwap } from "@bitwarden/angular/utils/extension-refresh-swap";
import {
AnonLayoutWrapperComponent,
@@ -98,7 +99,6 @@ import { TrashComponent } from "../vault/popup/settings/trash.component";
import { VaultSettingsV2Component } from "../vault/popup/settings/vault-settings-v2.component";
import { VaultSettingsComponent } from "../vault/popup/settings/vault-settings.component";
-import { extensionRefreshRedirect } from "./extension-refresh-route-utils";
import { debounceNavigationGuard } from "./services/debounce-navigation.service";
import { TabsV2Component } from "./tabs-v2.component";
import { TabsComponent } from "./tabs.component";
diff --git a/apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts b/apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts
index 9022a3b0489..20b39c5a88d 100644
--- a/apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts
+++ b/apps/browser/src/vault/popup/components/vault-v2/vault-ui-onboarding/vault-ui-onboarding.component.ts
@@ -13,13 +13,13 @@ import {
const announcementIcon = svgIcon`
+
+
();
constructor(
@@ -171,9 +179,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
private messagingService: MessagingService,
private formBuilder: FormBuilder,
private organizationApiService: OrganizationApiServiceAbstraction,
+ private configService: ConfigService,
+ private billingApiService: BillingApiServiceAbstraction,
) {}
async ngOnInit(): Promise {
+ this.deprecateStripeSourcesAPI = await this.configService.getFeatureFlag(
+ FeatureFlag.AC2476_DeprecateStripeSourcesAPI,
+ );
+
if (this.dialogParams.organizationId) {
this.currentPlanName = this.resolvePlanName(this.dialogParams.productTierType);
this.sub =
@@ -595,7 +609,16 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
}
changedCountry() {
- if (this.paymentComponent && this.taxComponent) {
+ if (this.deprecateStripeSourcesAPI && this.paymentV2Component && this.taxComponent) {
+ this.paymentV2Component.showBankAccount = this.taxComponent.country === "US";
+
+ if (
+ !this.paymentV2Component.showBankAccount &&
+ this.paymentV2Component.selected === PaymentMethodType.BankAccount
+ ) {
+ this.paymentV2Component.select(PaymentMethodType.Card);
+ }
+ } else if (this.paymentComponent && this.taxComponent) {
this.paymentComponent!.hideBank = this.taxComponent?.taxFormGroup?.value.country !== "US";
// Bank Account payments are only available for US customers
if (
@@ -616,7 +639,7 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
const doSubmit = async (): Promise => {
let orgId: string = null;
- orgId = await this.updateOrganization(orgId);
+ orgId = await this.updateOrganization();
this.toastService.showToast({
variant: "success",
title: null,
@@ -650,12 +673,15 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
this.dialogRef.close();
};
- private async updateOrganization(orgId: string) {
+ private async updateOrganization() {
const request = new OrganizationUpgradeRequest();
if (this.selectedPlan.productTier !== ProductTierType.Families) {
request.additionalSeats = this.organization.seats;
}
- request.additionalStorageGb = this.organization.maxStorageGb;
+ if (this.organization.maxStorageGb > this.selectedPlan.PasswordManager.baseStorageGb) {
+ request.additionalStorageGb =
+ this.organization.maxStorageGb - this.selectedPlan.PasswordManager.baseStorageGb;
+ }
request.premiumAccessAddon =
this.selectedPlan.PasswordManager.hasPremiumAccessOption &&
this.formGroup.controls.premiumAccessAddon.value;
@@ -669,13 +695,33 @@ export class ChangePlanDialogComponent implements OnInit, OnDestroy {
this.buildSecretsManagerRequest(request);
if (this.upgradeRequiresPaymentMethod || this.showPayment) {
- const tokenResult = await this.paymentComponent.createPaymentToken();
- const paymentRequest = new PaymentRequest();
- paymentRequest.paymentToken = tokenResult[0];
- paymentRequest.paymentMethodType = tokenResult[1];
- paymentRequest.country = this.taxComponent.taxFormGroup?.value.country;
- paymentRequest.postalCode = this.taxComponent.taxFormGroup?.value.postalCode;
- await this.organizationApiService.updatePayment(this.organizationId, paymentRequest);
+ if (this.deprecateStripeSourcesAPI) {
+ const tokenizedPaymentSource = await this.paymentV2Component.tokenize();
+ const updatePaymentMethodRequest = new UpdatePaymentMethodRequest();
+ updatePaymentMethodRequest.paymentSource = tokenizedPaymentSource;
+ updatePaymentMethodRequest.taxInformation = {
+ country: this.taxComponent.country,
+ postalCode: this.taxComponent.postalCode,
+ taxId: this.taxComponent.taxId,
+ line1: this.taxComponent.line1,
+ line2: this.taxComponent.line2,
+ city: this.taxComponent.city,
+ state: this.taxComponent.state,
+ };
+
+ await this.billingApiService.updateOrganizationPaymentMethod(
+ this.organizationId,
+ updatePaymentMethodRequest,
+ );
+ } else {
+ const tokenResult = await this.paymentComponent.createPaymentToken();
+ const paymentRequest = new PaymentRequest();
+ paymentRequest.paymentToken = tokenResult[0];
+ paymentRequest.paymentMethodType = tokenResult[1];
+ paymentRequest.country = this.taxComponent.taxFormGroup?.value.country;
+ paymentRequest.postalCode = this.taxComponent.taxFormGroup?.value.postalCode;
+ await this.organizationApiService.updatePayment(this.organizationId, paymentRequest);
+ }
}
// Backfill pub/priv key if necessary
diff --git a/apps/web/src/app/billing/shared/payment/payment-v2.component.ts b/apps/web/src/app/billing/shared/payment/payment-v2.component.ts
index 8d7e8d7a0ce..fa2b53fc7b5 100644
--- a/apps/web/src/app/billing/shared/payment/payment-v2.component.ts
+++ b/apps/web/src/app/billing/shared/payment/payment-v2.component.ts
@@ -86,7 +86,7 @@ export class PaymentV2Component implements OnInit, OnDestroy {
/** Programmatically select the provided payment method. */
select = (paymentMethod: PaymentMethodType) => {
- this.formGroup.value.paymentMethod = paymentMethod;
+ this.formGroup.get("paymentMethod").patchValue(paymentMethod);
};
protected submit = async () => {
diff --git a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts
index b5f910cd1a0..09e7484b673 100644
--- a/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts
+++ b/apps/web/src/app/vault/components/vault-items/vault-collection-row.component.ts
@@ -34,7 +34,6 @@ export class VaultCollectionRowComponent {
@Input() organizations: Organization[];
@Input() groups: GroupView[];
@Input() showPermissionsColumn: boolean;
- @Input() restrictProviderAccess: boolean;
@Output() onEvent = new EventEmitter();
@@ -74,10 +73,7 @@ export class VaultCollectionRowComponent {
}
get permissionText() {
- if (
- this.collection.id == Unassigned &&
- this.organization?.canEditUnassignedCiphers(this.restrictProviderAccess)
- ) {
+ if (this.collection.id == Unassigned && this.organization?.canEditUnassignedCiphers) {
return this.i18nService.t("canEdit");
}
if ((this.collection as CollectionAdminView).assigned) {
diff --git a/apps/web/src/app/vault/components/vault-items/vault-items.component.html b/apps/web/src/app/vault/components/vault-items/vault-items.component.html
index ec7b843afc9..7b427d2f124 100644
--- a/apps/web/src/app/vault/components/vault-items/vault-items.component.html
+++ b/apps/web/src/app/vault/components/vault-items/vault-items.component.html
@@ -106,7 +106,6 @@
[canDeleteCollection]="canDeleteCollection(item.collection)"
[canEditCollection]="canEditCollection(item.collection)"
[canViewCollectionInfo]="canViewCollectionInfo(item.collection)"
- [restrictProviderAccess]="restrictProviderAccess"
[checked]="selection.isSelected(item)"
(checkedToggled)="selection.toggle(item)"
(onEvent)="event($event)"
diff --git a/apps/web/src/app/vault/components/vault-items/vault-items.component.ts b/apps/web/src/app/vault/components/vault-items/vault-items.component.ts
index d876ccca6f9..e70269ede0b 100644
--- a/apps/web/src/app/vault/components/vault-items/vault-items.component.ts
+++ b/apps/web/src/app/vault/components/vault-items/vault-items.component.ts
@@ -46,7 +46,6 @@ export class VaultItemsComponent {
@Input() viewingOrgVault: boolean;
@Input() addAccessStatus: number;
@Input() addAccessToggle: boolean;
- @Input() restrictProviderAccess: boolean;
@Input() vaultBulkManagementActionEnabled = false;
@Input() activeCollection: CollectionView | undefined;
@@ -213,10 +212,7 @@ export class VaultItemsComponent {
}
const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId);
- return (
- (organization.canEditAllCiphers(this.restrictProviderAccess) && this.viewingOrgVault) ||
- cipher.edit
- );
+ return (organization.canEditAllCiphers && this.viewingOrgVault) || cipher.edit;
}
protected canManageCollection(cipher: CipherView) {
@@ -306,8 +302,7 @@ export class VaultItemsComponent {
const [orgId] = uniqueCipherOrgIds;
const organization = this.allOrganizations.find((o) => o.id === orgId);
- const canEditOrManageAllCiphers =
- organization?.canEditAllCiphers(this.restrictProviderAccess) && this.viewingOrgVault;
+ const canEditOrManageAllCiphers = organization?.canEditAllCiphers && this.viewingOrgVault;
const collectionNotSelected =
this.selection.selected.filter((item) => item.collection).length === 0;
diff --git a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts
index 617628a0b37..e787a31f6e2 100644
--- a/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts
+++ b/apps/web/src/app/vault/individual-vault/bulk-action-dialogs/bulk-delete-dialog/bulk-delete-dialog.component.ts
@@ -1,11 +1,8 @@
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
import { Component, Inject } from "@angular/core";
-import { firstValueFrom } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
-import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
-import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
import { CipherService } from "@bitwarden/common/vault/abstractions/cipher.service";
@@ -54,10 +51,6 @@ export class BulkDeleteDialogComponent {
collections: CollectionView[];
unassignedCiphers: string[];
- private restrictProviderAccess$ = this.configService.getFeatureFlag$(
- FeatureFlag.RestrictProviderAccess,
- );
-
constructor(
@Inject(DIALOG_DATA) params: BulkDeleteDialogParams,
private dialogRef: DialogRef,
@@ -66,7 +59,6 @@ export class BulkDeleteDialogComponent {
private i18nService: I18nService,
private apiService: ApiService,
private collectionService: CollectionService,
- private configService: ConfigService,
) {
this.cipherIds = params.cipherIds ?? [];
this.permanent = params.permanent;
@@ -82,19 +74,13 @@ export class BulkDeleteDialogComponent {
protected submit = async () => {
const deletePromises: Promise[] = [];
- const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$);
// Unassigned ciphers under an Owner/Admin OR Custom Users With Edit will call the deleteCiphersAdmin method
- if (
- this.unassignedCiphers.length &&
- this.organization.canEditUnassignedCiphers(restrictProviderAccess)
- ) {
+ if (this.unassignedCiphers.length && this.organization.canEditUnassignedCiphers) {
deletePromises.push(this.deleteCiphersAdmin(this.unassignedCiphers));
}
if (this.cipherIds.length) {
- const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$);
-
- if (!this.organization || !this.organization.canEditAllCiphers(restrictProviderAccess)) {
+ if (!this.organization || !this.organization.canEditAllCiphers) {
deletePromises.push(this.deleteCiphers());
} else {
deletePromises.push(this.deleteCiphersAdmin(this.cipherIds));
@@ -126,8 +112,7 @@ export class BulkDeleteDialogComponent {
};
private async deleteCiphers(): Promise {
- const restrictProviderAccess = await firstValueFrom(this.restrictProviderAccess$);
- const asAdmin = this.organization?.canEditAllCiphers(restrictProviderAccess);
+ const asAdmin = this.organization?.canEditAllCiphers;
if (this.permanent) {
await this.cipherService.deleteManyWithServer(this.cipherIds, asAdmin);
} else {
diff --git a/apps/web/src/app/vault/individual-vault/collections.component.html b/apps/web/src/app/vault/individual-vault/collections.component.html
index e4029ef8669..028d91ad346 100644
--- a/apps/web/src/app/vault/individual-vault/collections.component.html
+++ b/apps/web/src/app/vault/individual-vault/collections.component.html
@@ -32,7 +32,7 @@
[(ngModel)]="$any(c).checked"
name="Collection[{{ i }}].Checked"
appStopProp
- [disabled]="!c.canEditItems(this.organization, this.restrictProviderAccess)"
+ [disabled]="!c.canEditItems(this.organization)"
/>
{{ c.name }}
diff --git a/apps/web/src/app/vault/individual-vault/collections.component.ts b/apps/web/src/app/vault/individual-vault/collections.component.ts
index cd52e41e38d..0fc5b88d611 100644
--- a/apps/web/src/app/vault/individual-vault/collections.component.ts
+++ b/apps/web/src/app/vault/individual-vault/collections.component.ts
@@ -4,7 +4,6 @@ import { Component, Inject, OnDestroy } from "@angular/core";
import { CollectionsComponent as BaseCollectionsComponent } from "@bitwarden/angular/admin-console/components/collections.component";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
-import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -25,7 +24,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService: CipherService,
organizationSerivce: OrganizationService,
logService: LogService,
- configService: ConfigService,
accountService: AccountService,
protected dialogRef: DialogRef,
@Inject(DIALOG_DATA) params: CollectionsDialogParams,
@@ -38,7 +36,6 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
cipherService,
organizationSerivce,
logService,
- configService,
accountService,
toastService,
);
@@ -55,7 +52,7 @@ export class CollectionsComponent extends BaseCollectionsComponent implements On
}
check(c: CollectionView, select?: boolean) {
- if (!c.canEditItems(this.organization, this.restrictProviderAccess)) {
+ if (!c.canEditItems(this.organization)) {
return;
}
(c as any).checked = select == null ? !(c as any).checked : select;
diff --git a/apps/web/src/app/vault/individual-vault/vault.component.ts b/apps/web/src/app/vault/individual-vault/vault.component.ts
index d47a8be2523..dcf62235d1b 100644
--- a/apps/web/src/app/vault/individual-vault/vault.component.ts
+++ b/apps/web/src/app/vault/individual-vault/vault.component.ts
@@ -1161,7 +1161,7 @@ export class VaultComponent implements OnInit, OnDestroy {
}
const organization = this.allOrganizations.find((o) => o.id === cipher.organizationId);
- return organization.canEditAllCiphers(false);
+ return organization.canEditAllCiphers;
}
private go(queryParams: any = null) {
diff --git a/apps/web/src/app/vault/individual-vault/view.component.ts b/apps/web/src/app/vault/individual-vault/view.component.ts
index 2a3865cd1d0..77019b6f32e 100644
--- a/apps/web/src/app/vault/individual-vault/view.component.ts
+++ b/apps/web/src/app/vault/individual-vault/view.component.ts
@@ -1,13 +1,11 @@
import { DIALOG_DATA, DialogConfig, DialogRef } from "@angular/cdk/dialog";
import { CommonModule } from "@angular/common";
-import { Component, Inject, OnInit, EventEmitter, OnDestroy } from "@angular/core";
+import { Component, EventEmitter, Inject, OnDestroy, OnInit } from "@angular/core";
import { Router } from "@angular/router";
import { Subject } from "rxjs";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
-import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
-import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
@@ -50,9 +48,7 @@ export class ViewComponent implements OnInit, OnDestroy {
cipher: CipherView;
onDeletedCipher = new EventEmitter();
cipherTypeString: string;
- cipherEditUrl: string;
organization: Organization;
- restrictProviderAccess = false;
protected destroy$ = new Subject();
@@ -67,7 +63,6 @@ export class ViewComponent implements OnInit, OnDestroy {
private toastService: ToastService,
private organizationService: OrganizationService,
private router: Router,
- private configService: ConfigService,
) {}
/**
@@ -79,9 +74,6 @@ export class ViewComponent implements OnInit, OnDestroy {
if (this.cipher.organizationId) {
this.organization = await this.organizationService.get(this.cipher.organizationId);
}
- this.restrictProviderAccess = await this.configService.getFeatureFlag(
- FeatureFlag.RestrictProviderAccess,
- );
}
/**
@@ -132,7 +124,7 @@ export class ViewComponent implements OnInit, OnDestroy {
* Helper method to delete cipher.
*/
protected async deleteCipher(): Promise {
- const asAdmin = this.organization?.canEditAllCiphers(this.restrictProviderAccess);
+ const asAdmin = this.organization?.canEditAllCiphers;
if (this.cipher.isDeleted) {
await this.cipherService.deleteWithServer(this.cipher.id, asAdmin);
} else {
diff --git a/apps/web/src/app/vault/org-vault/add-edit.component.ts b/apps/web/src/app/vault/org-vault/add-edit.component.ts
index 6886da371ec..9129ed9cda5 100644
--- a/apps/web/src/app/vault/org-vault/add-edit.component.ts
+++ b/apps/web/src/app/vault/org-vault/add-edit.component.ts
@@ -83,7 +83,7 @@ export class AddEditComponent extends BaseAddEditComponent {
}
protected loadCollections() {
- if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
+ if (!this.organization.canEditAllCiphers) {
return super.loadCollections();
}
return Promise.resolve(this.collections);
@@ -93,10 +93,7 @@ export class AddEditComponent extends BaseAddEditComponent {
// Calling loadCipher first to assess if the cipher is unassigned. If null use apiService getCipherAdmin
const firstCipherCheck = await super.loadCipher();
- if (
- !this.organization.canEditAllCiphers(this.restrictProviderAccess) &&
- firstCipherCheck != null
- ) {
+ if (!this.organization.canEditAllCiphers && firstCipherCheck != null) {
return firstCipherCheck;
}
const response = await this.apiService.getCipherAdmin(this.cipherId);
@@ -109,7 +106,7 @@ export class AddEditComponent extends BaseAddEditComponent {
}
protected encryptCipher(userId: UserId) {
- if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
+ if (!this.organization.canEditAllCiphers) {
return super.encryptCipher(userId);
}
@@ -117,7 +114,7 @@ export class AddEditComponent extends BaseAddEditComponent {
}
protected async deleteCipher() {
- if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
+ if (!this.organization.canEditAllCiphers) {
return super.deleteCipher();
}
return this.cipher.isDeleted
diff --git a/apps/web/src/app/vault/org-vault/attachments.component.ts b/apps/web/src/app/vault/org-vault/attachments.component.ts
index f02ac693108..9ebb917aaf5 100644
--- a/apps/web/src/app/vault/org-vault/attachments.component.ts
+++ b/apps/web/src/app/vault/org-vault/attachments.component.ts
@@ -1,12 +1,9 @@
import { Component, OnInit } from "@angular/core";
-import { firstValueFrom } from "rxjs";
import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { BillingAccountProfileStateService } from "@bitwarden/common/billing/abstractions/account/billing-account-profile-state.service";
-import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
-import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { CryptoService } from "@bitwarden/common/platform/abstractions/crypto.service";
import { FileDownloadService } from "@bitwarden/common/platform/abstractions/file-download/file-download.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
@@ -30,8 +27,6 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
viewOnly = false;
organization: Organization;
- private restrictProviderAccess = false;
-
constructor(
cipherService: CipherService,
i18nService: I18nService,
@@ -44,7 +39,6 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
dialogService: DialogService,
billingAccountProfileStateService: BillingAccountProfileStateService,
accountService: AccountService,
- private configService: ConfigService,
) {
super(
cipherService,
@@ -63,22 +57,16 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
async ngOnInit() {
await super.ngOnInit();
- this.restrictProviderAccess = await firstValueFrom(
- this.configService.getFeatureFlag$(FeatureFlag.RestrictProviderAccess),
- );
}
protected async reupload(attachment: AttachmentView) {
- if (
- this.organization.canEditAllCiphers(this.restrictProviderAccess) &&
- this.showFixOldAttachments(attachment)
- ) {
+ if (this.organization.canEditAllCiphers && this.showFixOldAttachments(attachment)) {
await super.reuploadCipherAttachment(attachment, true);
}
}
protected async loadCipher() {
- if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
+ if (!this.organization.canEditAllCiphers) {
return await super.loadCipher();
}
const response = await this.apiService.getCipherAdmin(this.cipherId);
@@ -90,20 +78,18 @@ export class AttachmentsComponent extends BaseAttachmentsComponent implements On
this.cipherDomain,
file,
userId,
- this.organization.canEditAllCiphers(this.restrictProviderAccess),
+ this.organization.canEditAllCiphers,
);
}
protected deleteCipherAttachment(attachmentId: string) {
- if (!this.organization.canEditAllCiphers(this.restrictProviderAccess)) {
+ if (!this.organization.canEditAllCiphers) {
return super.deleteCipherAttachment(attachmentId);
}
return this.apiService.deleteCipherAttachmentAdmin(this.cipherId, attachmentId);
}
protected showFixOldAttachments(attachment: AttachmentView) {
- return (
- attachment.key == null && this.organization.canEditAllCiphers(this.restrictProviderAccess)
- );
+ return attachment.key == null && this.organization.canEditAllCiphers;
}
}
diff --git a/apps/web/src/app/vault/org-vault/collections.component.ts b/apps/web/src/app/vault/org-vault/collections.component.ts
index 72816d53214..877e7dfe161 100644
--- a/apps/web/src/app/vault/org-vault/collections.component.ts
+++ b/apps/web/src/app/vault/org-vault/collections.component.ts
@@ -5,7 +5,6 @@ import { ApiService } from "@bitwarden/common/abstractions/api.service";
import { OrganizationService } from "@bitwarden/common/admin-console/abstractions/organization/organization.service.abstraction";
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
-import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { PlatformUtilsService } from "@bitwarden/common/platform/abstractions/platform-utils.service";
@@ -37,7 +36,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
organizationService: OrganizationService,
private apiService: ApiService,
logService: LogService,
- configService: ConfigService,
accountService: AccountService,
protected dialogRef: DialogRef,
@Inject(DIALOG_DATA) params: OrgVaultCollectionsDialogParams,
@@ -50,7 +48,6 @@ export class CollectionsComponent extends BaseCollectionsComponent {
cipherService,
organizationService,
logService,
- configService,
accountService,
dialogRef,
params,
@@ -65,10 +62,7 @@ export class CollectionsComponent extends BaseCollectionsComponent {
protected async loadCipher() {
// if cipher is unassigned use apiService. We can see this by looking at this.collectionIds
- if (
- !this.organization.canEditAllCiphers(this.restrictProviderAccess) &&
- this.collectionIds.length !== 0
- ) {
+ if (!this.organization.canEditAllCiphers && this.collectionIds.length !== 0) {
return await super.loadCipher();
}
const response = await this.apiService.getCipherAdmin(this.cipherId);
@@ -90,10 +84,7 @@ export class CollectionsComponent extends BaseCollectionsComponent {
}
protected saveCollections() {
- if (
- this.organization.canEditAllCiphers(this.restrictProviderAccess) ||
- this.collectionIds.length === 0
- ) {
+ if (this.organization.canEditAllCiphers || this.collectionIds.length === 0) {
const request = new CipherCollectionsRequest(this.cipherDomain.collectionIds);
return this.apiService.putCipherCollectionsAdmin(this.cipherId, request);
} else {
diff --git a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html
index f583055687c..9189e646d28 100644
--- a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html
+++ b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.html
@@ -93,14 +93,17 @@
-
+
diff --git a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts
index d9930d22716..5e64067a826 100644
--- a/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts
+++ b/apps/web/src/app/vault/org-vault/vault-header/vault-header.component.ts
@@ -13,11 +13,11 @@ import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.servic
import { CipherType } from "@bitwarden/common/vault/enums";
import { TreeNode } from "@bitwarden/common/vault/models/domain/tree-node";
import {
- DialogService,
- SimpleDialogOptions,
BreadcrumbsModule,
+ DialogService,
MenuModule,
SearchModule,
+ SimpleDialogOptions,
} from "@bitwarden/components";
import { HeaderModule } from "../../../layouts/header/header.module";
@@ -88,8 +88,6 @@ export class VaultHeaderComponent implements OnInit {
protected CollectionDialogTabType = CollectionDialogTabType;
protected organizations$ = this.organizationService.organizations$;
- protected restrictProviderAccessFlag = false;
-
/**
* Whether the extension refresh feature flag is enabled.
*/
@@ -108,9 +106,6 @@ export class VaultHeaderComponent implements OnInit {
) {}
async ngOnInit() {
- this.restrictProviderAccessFlag = await this.configService.getFeatureFlag(
- FeatureFlag.RestrictProviderAccess,
- );
this.extensionRefreshEnabled = await this.configService.getFeatureFlag(
FeatureFlag.ExtensionRefresh,
);
@@ -245,11 +240,7 @@ export class VaultHeaderComponent implements OnInit {
}
get canCreateCipher(): boolean {
- if (
- this.organization?.isProviderUser &&
- this.restrictProviderAccessFlag &&
- !this.organization?.isMember
- ) {
+ if (this.organization?.isProviderUser && !this.organization?.isMember) {
return false;
}
return true;
diff --git a/apps/web/src/app/vault/org-vault/vault.component.html b/apps/web/src/app/vault/org-vault/vault.component.html
index 63160abea69..ed7f6b1e3ed 100644
--- a/apps/web/src/app/vault/org-vault/vault.component.html
+++ b/apps/web/src/app/vault/org-vault/vault.component.html
@@ -70,7 +70,6 @@
[viewingOrgVault]="true"
[addAccessStatus]="addAccessStatus$ | async"
[addAccessToggle]="showAddAccessToggle"
- [restrictProviderAccess]="restrictProviderAccessEnabled"
>
diff --git a/apps/web/src/app/vault/org-vault/vault.component.ts b/apps/web/src/app/vault/org-vault/vault.component.ts
index f9652fe08ca..add1ecbe3e5 100644
--- a/apps/web/src/app/vault/org-vault/vault.component.ts
+++ b/apps/web/src/app/vault/org-vault/vault.component.ts
@@ -43,9 +43,7 @@ import { OrganizationService } from "@bitwarden/common/admin-console/abstraction
import { Organization } from "@bitwarden/common/admin-console/models/domain/organization";
import { AccountService } from "@bitwarden/common/auth/abstractions/account.service";
import { EventType } from "@bitwarden/common/enums";
-import { FeatureFlag } from "@bitwarden/common/enums/feature-flag.enum";
import { BroadcasterService } from "@bitwarden/common/platform/abstractions/broadcaster.service";
-import { ConfigService } from "@bitwarden/common/platform/abstractions/config/config.service";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { LogService } from "@bitwarden/common/platform/abstractions/log.service";
import { MessagingService } from "@bitwarden/common/platform/abstractions/messaging.service";
@@ -172,17 +170,8 @@ export class VaultComponent implements OnInit, OnDestroy {
protected orgRevokedUsers: OrganizationUserUserDetailsResponse[];
- private _restrictProviderAccessFlagEnabled: boolean;
- protected get restrictProviderAccessEnabled(): boolean {
- return this._restrictProviderAccessFlagEnabled;
- }
-
protected get hideVaultFilters(): boolean {
- return (
- this.restrictProviderAccessEnabled &&
- this.organization?.isProviderUser &&
- !this.organization?.isMember
- );
+ return this.organization?.isProviderUser && !this.organization?.isMember;
}
private searchText$ = new Subject();
@@ -218,7 +207,6 @@ export class VaultComponent implements OnInit, OnDestroy {
private apiService: ApiService,
private collectionService: CollectionService,
private organizationUserApiService: OrganizationUserApiService,
- protected configService: ConfigService,
private toastService: ToastService,
private accountService: AccountService,
) {}
@@ -230,10 +218,6 @@ export class VaultComponent implements OnInit, OnDestroy {
: "trashCleanupWarning",
);
- this._restrictProviderAccessFlagEnabled = await this.configService.getFeatureFlag(
- FeatureFlag.RestrictProviderAccess,
- );
-
const filter$ = this.routedVaultFilterService.filter$;
const organizationId$ = filter$.pipe(
map((filter) => filter.organizationId),
@@ -325,7 +309,7 @@ export class VaultComponent implements OnInit, OnDestroy {
this.editableCollections$ = this.allCollectionsWithoutUnassigned$.pipe(
map((collections) => {
// Users that can edit all ciphers can implicitly add to / edit within any collection
- if (this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled)) {
+ if (this.organization.canEditAllCiphers) {
return collections;
}
// The user is only allowed to add/edit items to assigned collections that are not readonly
@@ -362,16 +346,12 @@ export class VaultComponent implements OnInit, OnDestroy {
// Restricted providers (who are not members) do not have access org cipher endpoint below
// Return early to avoid 404 response
- if (
- this.restrictProviderAccessEnabled &&
- !organization.isMember &&
- organization.isProviderUser
- ) {
+ if (!organization.isMember && organization.isProviderUser) {
return [];
}
// If the user can edit all ciphers for the organization then fetch them ALL.
- if (organization.canEditAllCiphers(this.restrictProviderAccessEnabled)) {
+ if (organization.canEditAllCiphers) {
ciphers = await this.cipherService.getAllFromApiForOrganization(organization.id);
} else {
// Otherwise, only fetch ciphers they have access to (includes unassigned for admins).
@@ -476,11 +456,8 @@ export class VaultComponent implements OnInit, OnDestroy {
]).pipe(
map(([filter, collection, organization]) => {
return (
- (filter.collectionId === Unassigned &&
- !organization.canEditUnassignedCiphers(this.restrictProviderAccessEnabled)) ||
- (!organization.canEditAllCiphers(this.restrictProviderAccessEnabled) &&
- collection != undefined &&
- !collection.node.assigned)
+ (filter.collectionId === Unassigned && !organization.canEditUnassignedCiphers) ||
+ (!organization.canEditAllCiphers && collection != undefined && !collection.node.assigned)
);
}),
shareReplay({ refCount: true, bufferSize: 1 }),
@@ -525,7 +502,7 @@ export class VaultComponent implements OnInit, OnDestroy {
}
const canEditCipher =
- organization.canEditAllCiphers(this.restrictProviderAccessEnabled) ||
+ organization.canEditAllCiphers ||
(await firstValueFrom(allCipherMap$))[cipherId] != undefined;
if (canEditCipher) {
@@ -758,15 +735,9 @@ export class VaultComponent implements OnInit, OnDestroy {
this.allCollectionsWithoutUnassigned$.pipe(
map((c) => {
return c.sort((a, b) => {
- if (
- a.canEditItems(this.organization, this.restrictProviderAccessEnabled) &&
- !b.canEditItems(this.organization, this.restrictProviderAccessEnabled)
- ) {
+ if (a.canEditItems(this.organization) && !b.canEditItems(this.organization)) {
return -1;
- } else if (
- !a.canEditItems(this.organization, this.restrictProviderAccessEnabled) &&
- b.canEditItems(this.organization, this.restrictProviderAccessEnabled)
- ) {
+ } else if (!a.canEditItems(this.organization) && b.canEditItems(this.organization)) {
return 1;
} else {
return a.name.localeCompare(b.name);
@@ -1001,9 +972,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const unassignedCiphers: string[] = [];
// If user has edit all Access no need to check for unassigned ciphers
- const canEditAll = this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled);
-
- if (canEditAll) {
+ if (this.organization.canEditAllCiphers) {
ciphers.map((cipher) => {
editAccessCiphers.push(cipher.id);
});
@@ -1042,7 +1011,7 @@ export class VaultComponent implements OnInit, OnDestroy {
}
async deleteCipher(c: CipherView): Promise {
- if (!c.edit && !this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled)) {
+ if (!c.edit && !this.organization.canEditAllCiphers) {
this.showMissingPermissionsError();
return;
}
@@ -1146,9 +1115,7 @@ export class VaultComponent implements OnInit, OnDestroy {
const canDeleteCollections =
collections == null || collections.every((c) => c.canDelete(organization));
const canDeleteCiphers =
- ciphers == null ||
- ciphers.every((c) => c.edit) ||
- this.organization.canEditAllCiphers(this.restrictProviderAccessEnabled);
+ ciphers == null || ciphers.every((c) => c.edit) || this.organization.canEditAllCiphers;
if (!canDeleteCiphers || !canDeleteCollections) {
this.showMissingPermissionsError();
@@ -1351,8 +1318,7 @@ export class VaultComponent implements OnInit, OnDestroy {
}
protected deleteCipherWithServer(id: string, permanent: boolean, isUnassigned: boolean) {
- const asAdmin =
- this.organization?.canEditAllCiphers(this.restrictProviderAccessEnabled) || isUnassigned;
+ const asAdmin = this.organization?.canEditAllCiphers || isUnassigned;
return permanent
? this.cipherService.deleteWithServer(id, asAdmin)
: this.cipherService.softDeleteWithServer(id, asAdmin);
diff --git a/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.html b/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.html
index 457eff37fac..2238fa9fc87 100644
--- a/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.html
+++ b/bitwarden_license/bit-web/src/app/secrets-manager/shared/new-menu.component.html
@@ -1,11 +1,6 @@
-