From 0c291bf79b1b4007bd3a5a2204cf3679b848395e Mon Sep 17 00:00:00 2001 From: Vincent Salucci <26154748+vincentsalucci@users.noreply.github.com> Date: Mon, 8 Apr 2024 13:24:27 -0500 Subject: [PATCH 1/2] [AC-2086] Limit admin access - Collection Modal (#8335) * feat: add view collection string, update button text, refs AC-2086 * feat: remove canEdit from Restricted Collection Access component, refs AC-2086 * feat: add view collection clicked flow, refs AC-2086 * fix: revert accidental svg icon changes, refs AC-2086 * feat: add input for access selector to hide multi select, refs AC-2086 * feat: apply readonly/disabled changes to access dialog, refs AC-2086 * fix: messages file conflict, refs AC-2086 * feat: apply disabled state to access selector, refs AC-2086 * fix: formatting, refs AC-2086 * fix: permission mode read only relocate, refs AC-2086 * fix: conform readonly casing, refs AC-2086 --- .../access-selector.component.html | 6 +- .../access-selector.component.ts | 8 ++ .../collection-dialog.component.html | 39 +++++--- .../collection-dialog.component.ts | 93 +++++++++++++++++-- .../collection-access-restricted.component.ts | 11 +-- .../app/vault/org-vault/vault.component.html | 6 +- .../app/vault/org-vault/vault.component.ts | 13 ++- apps/web/src/locales/en/messages.json | 6 ++ 8 files changed, 145 insertions(+), 37 deletions(-) diff --git a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html index 16a24781dfa..f4c9c840ef5 100644 --- a/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html +++ b/apps/web/src/app/admin-console/organizations/shared/components/access-selector/access-selector.component.html @@ -22,7 +22,7 @@ - + {{ selectorLabelText }}
@@ -139,7 +139,7 @@ `, }) export class CollectionAccessRestrictedComponent { protected icon = icon; - @Input() canEdit = false; - - @Output() editInfoClicked = new EventEmitter(); + @Output() viewCollectionClicked = new EventEmitter(); } 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 391f412f1e7..bcbd56630c0 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.html +++ b/apps/web/src/app/vault/org-vault/vault.component.html @@ -99,11 +99,9 @@ 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 d7cc70c5836..cb01951fcc3 100644 --- a/apps/web/src/app/vault/org-vault/vault.component.ts +++ b/apps/web/src/app/vault/org-vault/vault.component.ts @@ -1058,9 +1058,18 @@ export class VaultComponent implements OnInit, OnDestroy { } } - async editCollection(c: CollectionView, tab: CollectionDialogTabType): Promise { + async editCollection( + c: CollectionView, + tab: CollectionDialogTabType, + readonly: boolean = false, + ): Promise { const dialog = openCollectionDialog(this.dialogService, { - data: { collectionId: c?.id, organizationId: this.organization?.id, initialTab: tab }, + data: { + collectionId: c?.id, + organizationId: this.organization?.id, + initialTab: tab, + readonly: readonly, + }, }); const result = await lastValueFrom(dialog.closed); diff --git a/apps/web/src/locales/en/messages.json b/apps/web/src/locales/en/messages.json index 1604057f70b..307c5be70cb 100644 --- a/apps/web/src/locales/en/messages.json +++ b/apps/web/src/locales/en/messages.json @@ -7501,6 +7501,9 @@ "collectionAccessRestricted": { "message": "Collection access is restricted" }, + "readOnlyCollectionAccess": { + "message": "You do not have access to manage this collection." + }, "grantCollectionAccess": { "message": "Grant groups or members access to this collection." }, @@ -7603,6 +7606,9 @@ "providerPortal": { "message": "Provider Portal" }, + "viewCollection": { + "message": "View collection" + }, "restrictedGroupAccess": { "message": "You cannot add yourself to groups." }, From 18ae698f8d562f4cc2ead7c438894969ebbb5a2a Mon Sep 17 00:00:00 2001 From: Conner Turnbull <133619638+cturnbull-bitwarden@users.noreply.github.com> Date: Mon, 8 Apr 2024 14:42:49 -0400 Subject: [PATCH 2/2] SM changes (#8531) --- .../organizations/organization-plans.component.ts | 10 +++++++--- .../organization-subscription-cloud.component.ts | 3 +++ .../providers/clients/clients.component.ts | 1 + libs/common/src/billing/enums/plan-type.enum.ts | 15 ++++++++++----- .../services/organization-billing.service.ts | 1 + 5 files changed, 22 insertions(+), 8 deletions(-) diff --git a/apps/web/src/app/billing/organizations/organization-plans.component.ts b/apps/web/src/app/billing/organizations/organization-plans.component.ts index 1242018673f..17eddbd33d5 100644 --- a/apps/web/src/app/billing/organizations/organization-plans.component.ts +++ b/apps/web/src/app/billing/organizations/organization-plans.component.ts @@ -47,7 +47,11 @@ interface OnSuccessArgs { organizationId: string; } -const Allowed2020PlanTypes = [ +const AllowedLegacyPlanTypes = [ + PlanType.TeamsMonthly2023, + PlanType.TeamsAnnually2023, + PlanType.EnterpriseAnnually2023, + PlanType.EnterpriseMonthly2023, PlanType.TeamsMonthly2020, PlanType.TeamsAnnually2020, PlanType.EnterpriseAnnually2020, @@ -278,7 +282,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { (!this.currentPlan || this.currentPlan.upgradeSortOrder < plan.upgradeSortOrder) && (!this.hasProvider || plan.product !== ProductType.TeamsStarter) && ((!this.isProviderQualifiedFor2020Plan() && this.planIsEnabled(plan)) || - (this.isProviderQualifiedFor2020Plan() && Allowed2020PlanTypes.includes(plan.type))), + (this.isProviderQualifiedFor2020Plan() && AllowedLegacyPlanTypes.includes(plan.type))), ); result.sort((planA, planB) => planA.displaySortOrder - planB.displaySortOrder); @@ -293,7 +297,7 @@ export class OrganizationPlansComponent implements OnInit, OnDestroy { (plan) => plan.product === selectedProductType && ((!this.isProviderQualifiedFor2020Plan() && this.planIsEnabled(plan)) || - (this.isProviderQualifiedFor2020Plan() && Allowed2020PlanTypes.includes(plan.type))), + (this.isProviderQualifiedFor2020Plan() && AllowedLegacyPlanTypes.includes(plan.type))), ) || []; result.sort((planA, planB) => planA.displaySortOrder - planB.displaySortOrder); diff --git a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts index 0810f79b8ea..2173d4c0ca1 100644 --- a/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts +++ b/apps/web/src/app/billing/organizations/organization-subscription-cloud.component.ts @@ -241,6 +241,8 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy return ( this.sub.planType === PlanType.EnterpriseAnnually || this.sub.planType === PlanType.EnterpriseMonthly || + this.sub.planType === PlanType.EnterpriseAnnually2023 || + this.sub.planType === PlanType.EnterpriseMonthly2023 || this.sub.planType === PlanType.EnterpriseAnnually2020 || this.sub.planType === PlanType.EnterpriseMonthly2020 || this.sub.planType === PlanType.EnterpriseAnnually2019 || @@ -254,6 +256,7 @@ export class OrganizationSubscriptionCloudComponent implements OnInit, OnDestroy } else if ( this.sub.planType === PlanType.FamiliesAnnually || this.sub.planType === PlanType.FamiliesAnnually2019 || + this.sub.planType === PlanType.TeamsStarter2023 || this.sub.planType === PlanType.TeamsStarter ) { if (this.isSponsoredSubscription) { diff --git a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts index 20e98ce0842..72cce7aac3c 100644 --- a/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts +++ b/bitwarden_license/bit-web/src/app/admin-console/providers/clients/clients.component.ts @@ -29,6 +29,7 @@ const DisallowedPlanTypes = [ PlanType.Free, PlanType.FamiliesAnnually2019, PlanType.FamiliesAnnually, + PlanType.TeamsStarter2023, PlanType.TeamsStarter, ]; diff --git a/libs/common/src/billing/enums/plan-type.enum.ts b/libs/common/src/billing/enums/plan-type.enum.ts index 38febc50e4b..c8977703454 100644 --- a/libs/common/src/billing/enums/plan-type.enum.ts +++ b/libs/common/src/billing/enums/plan-type.enum.ts @@ -11,9 +11,14 @@ export enum PlanType { TeamsAnnually2020 = 9, EnterpriseMonthly2020 = 10, EnterpriseAnnually2020 = 11, - TeamsMonthly = 12, - TeamsAnnually = 13, - EnterpriseMonthly = 14, - EnterpriseAnnually = 15, - TeamsStarter = 16, + TeamsMonthly2023 = 12, + TeamsAnnually2023 = 13, + EnterpriseMonthly2023 = 14, + EnterpriseAnnually2023 = 15, + TeamsStarter2023 = 16, + TeamsMonthly = 17, + TeamsAnnually = 18, + EnterpriseMonthly = 19, + EnterpriseAnnually = 20, + TeamsStarter = 21, } diff --git a/libs/common/src/billing/services/organization-billing.service.ts b/libs/common/src/billing/services/organization-billing.service.ts index a9437e288cc..f2df30e4e01 100644 --- a/libs/common/src/billing/services/organization-billing.service.ts +++ b/libs/common/src/billing/services/organization-billing.service.ts @@ -81,6 +81,7 @@ export class OrganizationBillingService implements OrganizationBillingServiceAbs case PlanType.Free: case PlanType.FamiliesAnnually: case PlanType.FamiliesAnnually2019: + case PlanType.TeamsStarter2023: case PlanType.TeamsStarter: return true; default: