feat: add permission checks to phone number API routes

This commit is contained in:
Nawaz Dhandala
2026-03-30 12:04:05 +01:00
parent 9adbd04538
commit e655385c4d
2 changed files with 113 additions and 1 deletions

View File

@@ -14,6 +14,7 @@ import ObjectID from "Common/Types/ObjectID";
import IncomingCallPolicyService from "Common/Server/Services/IncomingCallPolicyService";
import ProjectService from "Common/Server/Services/ProjectService";
import UserMiddleware from "Common/Server/Middleware/UserAuthorization";
import Permission from "Common/Types/Permission";
import Express, {
ExpressRequest,
ExpressResponse,
@@ -33,6 +34,14 @@ router.post(
"/search",
UserMiddleware.getUserMiddleware,
UserMiddleware.requireUserAuthentication,
UserMiddleware.requirePermission({
permissions: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadProjectIncomingCallPolicy,
],
}),
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body as JSONObject;
@@ -159,6 +168,14 @@ router.post(
"/list-owned",
UserMiddleware.getUserMiddleware,
UserMiddleware.requireUserAuthentication,
UserMiddleware.requirePermission({
permissions: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.ReadProjectIncomingCallPolicy,
],
}),
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body as JSONObject;
@@ -244,6 +261,14 @@ router.post(
"/assign-existing",
UserMiddleware.getUserMiddleware,
UserMiddleware.requireUserAuthentication,
UserMiddleware.requirePermission({
permissions: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditProjectIncomingCallPolicy,
],
}),
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body as JSONObject;
@@ -394,6 +419,14 @@ router.post(
"/purchase",
UserMiddleware.getUserMiddleware,
UserMiddleware.requireUserAuthentication,
UserMiddleware.requirePermission({
permissions: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditProjectIncomingCallPolicy,
],
}),
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const body: JSONObject = req.body as JSONObject;
@@ -539,6 +572,14 @@ router.delete(
"/release/:incomingCallPolicyId",
UserMiddleware.getUserMiddleware,
UserMiddleware.requireUserAuthentication,
UserMiddleware.requirePermission({
permissions: [
Permission.ProjectOwner,
Permission.ProjectAdmin,
Permission.ProjectMember,
Permission.EditProjectIncomingCallPolicy,
],
}),
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
try {
const incomingCallPolicyId: ObjectID | undefined = req.params[

View File

@@ -26,8 +26,11 @@ import { JSONObject } from "../../Types/JSON";
import JSONFunctions from "../../Types/JSONFunctions";
import JSONWebTokenData from "../../Types/JsonWebTokenData";
import ObjectID from "../../Types/ObjectID";
import {
import NotAuthorizedException from "../../Types/Exception/NotAuthorizedException";
import Permission, {
PermissionHelper,
UserGlobalAccessPermission,
UserPermission,
UserTenantAccessPermission,
} from "../../Types/Permission";
import UserType from "../../Types/UserType";
@@ -360,6 +363,74 @@ export default class UserMiddleware {
return next();
}
public static requirePermission(data: {
permissions: Array<Permission>;
}): (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
) => Promise<void> {
return async (
req: ExpressRequest,
res: ExpressResponse,
next: NextFunction,
): Promise<void> => {
const oneuptimeRequest: OneUptimeRequest = req as OneUptimeRequest;
// Master admins bypass permission checks
if (oneuptimeRequest.userType === UserType.MasterAdmin) {
return next();
}
const tenantId: ObjectID | undefined = oneuptimeRequest.tenantId;
if (!tenantId) {
return Response.sendErrorResponse(
req,
res,
new NotAuthorizedException(
"Project ID is required to access this resource.",
),
);
}
const userTenantPermission: UserTenantAccessPermission | undefined =
oneuptimeRequest.userTenantAccessPermission?.[tenantId.toString()];
if (!userTenantPermission) {
return Response.sendErrorResponse(
req,
res,
new NotAuthorizedException(
"You do not have permission to access this project.",
),
);
}
const userPermissions: Array<Permission> =
userTenantPermission.permissions.map(
(p: UserPermission) => p.permission,
);
if (
!PermissionHelper.doesPermissionsIntersect(
userPermissions,
data.permissions,
)
) {
return Response.sendErrorResponse(
req,
res,
new NotAuthorizedException(
"You do not have the required permission to perform this action.",
),
);
}
return next();
};
}
@CaptureSpan()
public static async getUserTenantAccessPermissionWithTenantId(data: {
req: ExpressRequest;