diff --git a/backend/src/ee/services/license/license-service.ts b/backend/src/ee/services/license/license-service.ts
index cfc42d038..e2cf09bb1 100644
--- a/backend/src/ee/services/license/license-service.ts
+++ b/backend/src/ee/services/license/license-service.ts
@@ -17,7 +17,7 @@ import { TIdentityOrgDALFactory } from "@app/services/identity/identity-org-dal"
import { TOrgDALFactory } from "@app/services/org/org-dal";
import { TProjectDALFactory } from "@app/services/project/project-dal";
-import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-permission";
+import { OrgPermissionBillingActions, OrgPermissionSubjects } from "../permission/org-permission";
import { TPermissionServiceFactory } from "../permission/permission-service";
import { BillingPlanRows, BillingPlanTableHead } from "./licence-enums";
import { TLicenseDALFactory } from "./license-dal";
@@ -288,7 +288,7 @@ export const licenseServiceFactory = ({
billingCycle
}: TOrgPlansTableDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const { data } = await licenseServerCloudApi.request.get(
`/api/license-server/v1/cloud-products?billing-cycle=${billingCycle}`
);
@@ -310,8 +310,10 @@ export const licenseServiceFactory = ({
success_url
}: TStartOrgTrialDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(
+ OrgPermissionBillingActions.ManageBilling,
+ OrgPermissionSubjects.Billing
+ );
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -338,8 +340,10 @@ export const licenseServiceFactory = ({
actorOrgId
}: TCreateOrgPortalSession) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Create, OrgPermissionSubjects.Billing);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(
+ OrgPermissionBillingActions.ManageBilling,
+ OrgPermissionSubjects.Billing
+ );
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -385,7 +389,7 @@ export const licenseServiceFactory = ({
const getOrgBillingInfo = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -413,7 +417,7 @@ export const licenseServiceFactory = ({
// returns org current plan feature table
const getOrgPlanTable = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -484,7 +488,7 @@ export const licenseServiceFactory = ({
const getOrgBillingDetails = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgBillInfoDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -509,7 +513,10 @@ export const licenseServiceFactory = ({
email
}: TUpdateOrgBillingDetailsDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(
+ OrgPermissionBillingActions.ManageBilling,
+ OrgPermissionSubjects.Billing
+ );
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -529,7 +536,7 @@ export const licenseServiceFactory = ({
const getOrgPmtMethods = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgPmtMethodsDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -556,7 +563,10 @@ export const licenseServiceFactory = ({
cancel_url
}: TAddOrgPmtMethodDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(
+ OrgPermissionBillingActions.ManageBilling,
+ OrgPermissionSubjects.Billing
+ );
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -585,7 +595,10 @@ export const licenseServiceFactory = ({
pmtMethodId
}: TDelOrgPmtMethodDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(
+ OrgPermissionBillingActions.ManageBilling,
+ OrgPermissionSubjects.Billing
+ );
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -602,7 +615,7 @@ export const licenseServiceFactory = ({
const getOrgTaxIds = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TGetOrgTaxIdDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -620,7 +633,10 @@ export const licenseServiceFactory = ({
const addOrgTaxId = async ({ actorId, actor, actorAuthMethod, actorOrgId, orgId, type, value }: TAddOrgTaxIdDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(
+ OrgPermissionBillingActions.ManageBilling,
+ OrgPermissionSubjects.Billing
+ );
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -641,7 +657,10 @@ export const licenseServiceFactory = ({
const delOrgTaxId = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId, taxId }: TDelOrgTaxIdDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(
+ OrgPermissionBillingActions.ManageBilling,
+ OrgPermissionSubjects.Billing
+ );
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -658,7 +677,7 @@ export const licenseServiceFactory = ({
const getOrgTaxInvoices = async ({ actorId, actor, actorOrgId, actorAuthMethod, orgId }: TOrgInvoiceDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
@@ -675,7 +694,7 @@ export const licenseServiceFactory = ({
const getOrgLicenses = async ({ orgId, actor, actorId, actorAuthMethod, actorOrgId }: TOrgLicensesDTO) => {
const { permission } = await permissionService.getOrgPermission(actor, actorId, orgId, actorAuthMethod, actorOrgId);
- ForbiddenError.from(permission).throwUnlessCan(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ ForbiddenError.from(permission).throwUnlessCan(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
const organization = await orgDAL.findOrgById(orgId);
if (!organization) {
diff --git a/backend/src/ee/services/permission/org-permission.ts b/backend/src/ee/services/permission/org-permission.ts
index 612914bcc..f0fe73d71 100644
--- a/backend/src/ee/services/permission/org-permission.ts
+++ b/backend/src/ee/services/permission/org-permission.ts
@@ -67,6 +67,11 @@ export enum OrgPermissionGroupActions {
RemoveMembers = "remove-members"
}
+export enum OrgPermissionBillingActions {
+ Read = "read",
+ ManageBilling = "manage-billing"
+}
+
export enum OrgPermissionSubjects {
Workspace = "workspace",
Role = "role",
@@ -107,7 +112,7 @@ export type OrgPermissionSet =
| [OrgPermissionActions, OrgPermissionSubjects.Ldap]
| [OrgPermissionGroupActions, OrgPermissionSubjects.Groups]
| [OrgPermissionActions, OrgPermissionSubjects.SecretScanning]
- | [OrgPermissionActions, OrgPermissionSubjects.Billing]
+ | [OrgPermissionBillingActions, OrgPermissionSubjects.Billing]
| [OrgPermissionIdentityActions, OrgPermissionSubjects.Identity]
| [OrgPermissionActions, OrgPermissionSubjects.Kms]
| [OrgPermissionActions, OrgPermissionSubjects.AuditLogs]
@@ -298,10 +303,8 @@ const buildAdminPermission = () => {
can(OrgPermissionGroupActions.AddMembers, OrgPermissionSubjects.Groups);
can(OrgPermissionGroupActions.RemoveMembers, OrgPermissionSubjects.Groups);
- can(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
- can(OrgPermissionActions.Create, OrgPermissionSubjects.Billing);
- can(OrgPermissionActions.Edit, OrgPermissionSubjects.Billing);
- can(OrgPermissionActions.Delete, OrgPermissionSubjects.Billing);
+ can(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
+ can(OrgPermissionBillingActions.ManageBilling, OrgPermissionSubjects.Billing);
can(OrgPermissionIdentityActions.Read, OrgPermissionSubjects.Identity);
can(OrgPermissionIdentityActions.Create, OrgPermissionSubjects.Identity);
@@ -362,7 +365,7 @@ const buildMemberPermission = () => {
can(OrgPermissionGroupActions.Read, OrgPermissionSubjects.Groups);
can(OrgPermissionActions.Read, OrgPermissionSubjects.Role);
can(OrgPermissionActions.Read, OrgPermissionSubjects.Settings);
- can(OrgPermissionActions.Read, OrgPermissionSubjects.Billing);
+ can(OrgPermissionBillingActions.Read, OrgPermissionSubjects.Billing);
can(OrgPermissionActions.Read, OrgPermissionSubjects.IncidentAccount);
can(OrgPermissionActions.Read, OrgPermissionSubjects.SecretScanning);
diff --git a/docs/internals/permissions/organization-permissions.mdx b/docs/internals/permissions/organization-permissions.mdx
index 6de3bd6fe..80c843851 100644
--- a/docs/internals/permissions/organization-permissions.mdx
+++ b/docs/internals/permissions/organization-permissions.mdx
@@ -142,12 +142,10 @@ Below is a comprehensive list of all available organization-level subjects and t
#### Subject: `billing`
-| Action | Description |
-| -------- | ------------------------------------------------ |
-| `read` | View billing information and subscription status |
-| `create` | Set up new payment methods or subscriptions |
-| `edit` | Modify billing details or subscription plans |
-| `delete` | Remove payment methods or cancel subscriptions |
+| Action | Description |
+| ---------------- | ------------------------------------------------ |
+| `read` | View billing information and subscription status |
+| `manage-billing` | Manage billing details and subscription plans |
### Templates & Automation
diff --git a/frontend/src/context/OrgPermissionContext/index.tsx b/frontend/src/context/OrgPermissionContext/index.tsx
index acbbf3902..fccd53935 100644
--- a/frontend/src/context/OrgPermissionContext/index.tsx
+++ b/frontend/src/context/OrgPermissionContext/index.tsx
@@ -2,6 +2,7 @@ export { useOrgPermission } from "./OrgPermissionContext";
export type { TOrgPermission } from "./types";
export {
OrgPermissionActions,
+ OrgPermissionBillingActions,
OrgPermissionGroupActions,
OrgPermissionIdentityActions,
OrgPermissionSubjects
diff --git a/frontend/src/context/OrgPermissionContext/types.ts b/frontend/src/context/OrgPermissionContext/types.ts
index a4bd202bf..59446eb07 100644
--- a/frontend/src/context/OrgPermissionContext/types.ts
+++ b/frontend/src/context/OrgPermissionContext/types.ts
@@ -7,6 +7,11 @@ export enum OrgPermissionActions {
Delete = "delete"
}
+export enum OrgPermissionBillingActions {
+ Read = "read",
+ ManageBilling = "manage-billing"
+}
+
export enum OrgGatewayPermissionActions {
// is there a better word for this. This mean can an identity be a gateway
CreateGateways = "create-gateways",
@@ -100,7 +105,7 @@ export type OrgPermissionSet =
| [OrgPermissionActions, OrgPermissionSubjects.Ldap]
| [OrgPermissionGroupActions, OrgPermissionSubjects.Groups]
| [OrgPermissionActions, OrgPermissionSubjects.SecretScanning]
- | [OrgPermissionActions, OrgPermissionSubjects.Billing]
+ | [OrgPermissionBillingActions, OrgPermissionSubjects.Billing]
| [OrgPermissionActions, OrgPermissionSubjects.Kms]
| [OrgPermissionAdminConsoleAction, OrgPermissionSubjects.AdminConsole]
| [OrgPermissionActions, OrgPermissionSubjects.AuditLogs]
diff --git a/frontend/src/context/index.tsx b/frontend/src/context/index.tsx
index 8b64ee58a..c19c990dd 100644
--- a/frontend/src/context/index.tsx
+++ b/frontend/src/context/index.tsx
@@ -2,6 +2,7 @@ export { useOrganization } from "./OrganizationContext";
export type { TOrgPermission } from "./OrgPermissionContext";
export {
OrgPermissionActions,
+ OrgPermissionBillingActions,
OrgPermissionGroupActions,
OrgPermissionIdentityActions,
OrgPermissionSubjects,
diff --git a/frontend/src/pages/organization/BillingPage/BillingPage.tsx b/frontend/src/pages/organization/BillingPage/BillingPage.tsx
index 0ffe5abbb..d0b71cc21 100644
--- a/frontend/src/pages/organization/BillingPage/BillingPage.tsx
+++ b/frontend/src/pages/organization/BillingPage/BillingPage.tsx
@@ -2,7 +2,7 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { OrgPermissionCan } from "@app/components/permissions";
-import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
+import { OrgPermissionBillingActions, OrgPermissionSubjects } from "@app/context";
import { BillingTabGroup } from "./components";
@@ -24,7 +24,7 @@ export const BillingPage = () => {