move action permission check to middleware

This commit is contained in:
Milo Schwartz 2024-11-05 23:55:46 -05:00
parent 03051878ef
commit 372e51c0a5
No known key found for this signature in database
48 changed files with 266 additions and 936 deletions

View file

@ -0,0 +1,36 @@
import { Request, Response, NextFunction } from "express";
import createHttpError from "http-errors";
import HttpCode from "@server/types/HttpCode";
import logger from "@server/logger";
import { checkUserActionPermission } from "@server/auth/actions";
import { ActionsEnum } from "@server/auth/actions";
export function verifyUserHasAction(action: ActionsEnum) {
return async function (
req: Request,
res: Response,
next: NextFunction
): Promise<any> {
try {
const hasPermission = await checkUserActionPermission(action, req);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission perform this action"
)
);
}
return next();
} catch (error) {
logger.error("Error verifying role access:", error);
return next(
createHttpError(
HttpCode.INTERNAL_SERVER_ERROR,
"Error verifying role access"
)
);
}
};
}

View file

@ -23,6 +23,8 @@ import {
verifyUserInRole, verifyUserInRole,
verifyUserAccess, verifyUserAccess,
} from "./auth"; } from "./auth";
import { verifyUserHasAction } from "./auth/verifyUserHasAction";
import { ActionsEnum } from "@server/auth/actions";
// Root routes // Root routes
export const unauthenticated = Router(); export const unauthenticated = Router();
@ -38,39 +40,92 @@ authenticated.use(verifySessionUserMiddleware);
authenticated.get("/org/checkId", org.checkId); authenticated.get("/org/checkId", org.checkId);
authenticated.put("/org", getUserOrgs, org.createOrg); authenticated.put("/org", getUserOrgs, org.createOrg);
authenticated.get("/orgs", getUserOrgs, org.listOrgs); // TODO we need to check the orgs here authenticated.get("/orgs", getUserOrgs, org.listOrgs); // TODO we need to check the orgs here
authenticated.get("/org/:orgId", verifyOrgAccess, org.getOrg); authenticated.get(
authenticated.post("/org/:orgId", verifyOrgAccess, org.updateOrg); "/org/:orgId",
verifyOrgAccess,
verifyUserHasAction(ActionsEnum.getOrg),
org.getOrg
);
authenticated.post(
"/org/:orgId",
verifyOrgAccess,
verifyUserHasAction(ActionsEnum.updateOrg),
org.updateOrg
);
// authenticated.delete("/org/:orgId", verifyOrgAccess, org.deleteOrg); // authenticated.delete("/org/:orgId", verifyOrgAccess, org.deleteOrg);
authenticated.put("/org/:orgId/site", verifyOrgAccess, site.createSite); authenticated.put(
authenticated.get("/org/:orgId/sites", verifyOrgAccess, site.listSites); "/org/:orgId/site",
authenticated.get("/org/:orgId/site/:niceId", verifyOrgAccess, site.getSite); verifyOrgAccess,
verifyUserHasAction(ActionsEnum.createSite),
site.createSite
);
authenticated.get(
"/org/:orgId/sites",
verifyOrgAccess,
verifyUserHasAction(ActionsEnum.listSites),
site.listSites
);
authenticated.get(
"/org/:orgId/site/:niceId",
verifyOrgAccess,
verifyUserHasAction(ActionsEnum.getSite),
site.getSite
);
authenticated.get( authenticated.get(
"/org/:orgId/pick-site-defaults", "/org/:orgId/pick-site-defaults",
verifyOrgAccess, verifyOrgAccess,
verifyUserHasAction(ActionsEnum.createSite),
site.pickSiteDefaults site.pickSiteDefaults
); );
authenticated.get("/site/:siteId", verifySiteAccess, site.getSite); authenticated.get(
// authenticated.get("/site/:siteId/roles", verifySiteAccess, site.listSiteRoles); "/site/:siteId",
authenticated.post("/site/:siteId", verifySiteAccess, site.updateSite); verifySiteAccess,
authenticated.delete("/site/:siteId", verifySiteAccess, site.deleteSite); verifyUserHasAction(ActionsEnum.getSite),
site.getSite
);
// authenticated.get(
// "/site/:siteId/roles",
// verifySiteAccess,
// verifyUserHasAction(ActionsEnum.listSiteRoles),
// site.listSiteRoles
// );
authenticated.post(
"/site/:siteId",
verifySiteAccess,
verifyUserHasAction(ActionsEnum.updateSite),
site.updateSite
);
authenticated.delete(
"/site/:siteId",
verifySiteAccess,
verifyUserHasAction(ActionsEnum.deleteSite),
site.deleteSite
);
authenticated.put( authenticated.put(
"/org/:orgId/site/:siteId/resource", "/org/:orgId/site/:siteId/resource",
verifyOrgAccess, verifyOrgAccess,
verifyUserHasAction(ActionsEnum.createResource),
resource.createResource resource.createResource
); );
authenticated.get("/site/:siteId/resources", resource.listResources); authenticated.get(
"/site/:siteId/resources",
verifyUserHasAction(ActionsEnum.listResources),
resource.listResources
);
authenticated.get( authenticated.get(
"/org/:orgId/resources", "/org/:orgId/resources",
verifyOrgAccess, verifyOrgAccess,
verifyUserHasAction(ActionsEnum.listResources),
resource.listResources resource.listResources
); );
authenticated.post( authenticated.post(
"/org/:orgId/create-invite", "/org/:orgId/create-invite",
verifyOrgAccess, verifyOrgAccess,
verifyUserHasAction(ActionsEnum.inviteUser),
user.inviteUser user.inviteUser
); // maybe make this /invite/create instead ); // maybe make this /invite/create instead
authenticated.post("/invite/accept", user.acceptInvite); authenticated.post("/invite/accept", user.acceptInvite);
@ -78,43 +133,56 @@ authenticated.post("/invite/accept", user.acceptInvite);
// authenticated.get( // authenticated.get(
// "/resource/:resourceId/roles", // "/resource/:resourceId/roles",
// verifyResourceAccess, // verifyResourceAccess,
// verifyUserHasAction(ActionsEnum.listResourceRoles),
// resource.listResourceRoles // resource.listResourceRoles
// ); // );
authenticated.get( authenticated.get(
"/resource/:resourceId", "/resource/:resourceId",
verifyResourceAccess, verifyResourceAccess,
verifyUserHasAction(ActionsEnum.getResource),
resource.getResource resource.getResource
); );
authenticated.post( authenticated.post(
"/resource/:resourceId", "/resource/:resourceId",
verifyResourceAccess, verifyResourceAccess,
verifyUserHasAction(ActionsEnum.updateResource),
resource.updateResource resource.updateResource
); );
authenticated.delete( authenticated.delete(
"/resource/:resourceId", "/resource/:resourceId",
verifyResourceAccess, verifyResourceAccess,
verifyUserHasAction(ActionsEnum.deleteResource),
resource.deleteResource resource.deleteResource
); );
authenticated.put( authenticated.put(
"/resource/:resourceId/target", "/resource/:resourceId/target",
verifyResourceAccess, verifyResourceAccess,
verifyUserHasAction(ActionsEnum.createTarget),
target.createTarget target.createTarget
); );
authenticated.get( authenticated.get(
"/resource/:resourceId/targets", "/resource/:resourceId/targets",
verifyResourceAccess, verifyResourceAccess,
verifyUserHasAction(ActionsEnum.listTargets),
target.listTargets target.listTargets
); );
authenticated.get("/target/:targetId", verifyTargetAccess, target.getTarget); authenticated.get(
"/target/:targetId",
verifyTargetAccess,
verifyUserHasAction(ActionsEnum.getTarget),
target.getTarget
);
authenticated.post( authenticated.post(
"/target/:targetId", "/target/:targetId",
verifyTargetAccess, verifyTargetAccess,
verifyUserHasAction(ActionsEnum.updateTarget),
target.updateTarget target.updateTarget
); );
authenticated.delete( authenticated.delete(
"/target/:targetId", "/target/:targetId",
verifyTargetAccess, verifyTargetAccess,
verifyUserHasAction(ActionsEnum.deleteTarget),
target.deleteTarget target.deleteTarget
); );
@ -122,25 +190,34 @@ authenticated.delete(
// "/org/:orgId/role", // "/org/:orgId/role",
// verifyOrgAccess, // verifyOrgAccess,
// verifyAdmin, // verifyAdmin,
// verifyUserHasAction(ActionsEnum.createRole),
// role.createRole // role.createRole
// ); // );
// authenticated.get("/org/:orgId/roles", verifyOrgAccess, role.listRoles); // authenticated.get(
// "/org/:orgId/roles",
// verifyOrgAccess,
// verifyUserHasAction(ActionsEnum.listRoles),
// role.listRoles
// );
// authenticated.get( // authenticated.get(
// "/role/:roleId", // "/role/:roleId",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.getRole),
// role.getRole // role.getRole
// ); // );
// authenticated.post( // authenticated.post(
// "/role/:roleId", // "/role/:roleId",
// verifyRoleAccess, // verifyRoleAccess,
// verifyAdmin, // verifyAdmin,
// verifyUserHasAction(ActionsEnum.updateRole),
// role.updateRole // role.updateRole
// ); // );
// authenticated.delete( // authenticated.delete(
// "/role/:roleId", // "/role/:roleId",
// verifyRoleAccess, // verifyRoleAccess,
// verifyAdmin, // verifyAdmin,
// verifyUserHasAction(ActionsEnum.deleteRole),
// role.deleteRole // role.deleteRole
// ); // );
@ -148,42 +225,49 @@ authenticated.delete(
// "/role/:roleId/site", // "/role/:roleId/site",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.addRoleSite),
// role.addRoleSite // role.addRoleSite
// ); // );
// authenticated.delete( // authenticated.delete(
// "/role/:roleId/site", // "/role/:roleId/site",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.removeRoleSite),
// role.removeRoleSite // role.removeRoleSite
// ); // );
// authenticated.get( // authenticated.get(
// "/role/:roleId/sites", // "/role/:roleId/sites",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.listRoleSites),
// role.listRoleSites // role.listRoleSites
// ); // );
// authenticated.put( // authenticated.put(
// "/role/:roleId/resource", // "/role/:roleId/resource",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.addRoleResource),
// role.addRoleResource // role.addRoleResource
// ); // );
// authenticated.delete( // authenticated.delete(
// "/role/:roleId/resource", // "/role/:roleId/resource",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.removeRoleResource),
// role.removeRoleResource // role.removeRoleResource
// ); // );
// authenticated.get( // authenticated.get(
// "/role/:roleId/resources", // "/role/:roleId/resources",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.listRoleResources),
// role.listRoleResources // role.listRoleResources
// ); // );
// authenticated.put( // authenticated.put(
// "/role/:roleId/action", // "/role/:roleId/action",
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyUserHasAction(ActionsEnum.addRoleAction),
// role.addRoleAction // role.addRoleAction
// ); // );
// authenticated.delete( // authenticated.delete(
@ -191,6 +275,7 @@ authenticated.delete(
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyAdmin, // verifyAdmin,
// verifyUserHasAction(ActionsEnum.removeRoleAction),
// role.removeRoleAction // role.removeRoleAction
// ); // );
// authenticated.get( // authenticated.get(
@ -198,16 +283,23 @@ authenticated.delete(
// verifyRoleAccess, // verifyRoleAccess,
// verifyUserInRole, // verifyUserInRole,
// verifyAdmin, // verifyAdmin,
// verifyUserHasAction(ActionsEnum.listRoleActions),
// role.listRoleActions // role.listRoleActions
// ); // );
unauthenticated.get("/user", verifySessionMiddleware, user.getUser); unauthenticated.get("/user", verifySessionMiddleware, user.getUser);
authenticated.get("/org/:orgId/users", verifyOrgAccess, user.listUsers); authenticated.get(
"/org/:orgId/users",
verifyOrgAccess,
verifyUserHasAction(ActionsEnum.listUsers),
user.listUsers
);
authenticated.delete( authenticated.delete(
"/org/:orgId/user/:userId", "/org/:orgId/user/:userId",
verifyOrgAccess, verifyOrgAccess,
verifyUserAccess, verifyUserAccess,
verifyUserHasAction(ActionsEnum.removeUser),
user.removeUserOrg user.removeUserOrg
); );
@ -215,24 +307,28 @@ authenticated.delete(
// "/user/:userId/site", // "/user/:userId/site",
// verifySiteAccess, // verifySiteAccess,
// verifyUserAccess, // verifyUserAccess,
// verifyUserHasAction(ActionsEnum.addRoleSite),
// role.addRoleSite // role.addRoleSite
// ); // );
// authenticated.delete( // authenticated.delete(
// "/user/:userId/site", // "/user/:userId/site",
// verifySiteAccess, // verifySiteAccess,
// verifyUserAccess, // verifyUserAccess,
// verifyUserHasAction(ActionsEnum.removeRoleSite),
// role.removeRoleSite // role.removeRoleSite
// ); // );
// authenticated.put( // authenticated.put(
// "/user/:userId/resource", // "/user/:userId/resource",
// verifyResourceAccess, // verifyResourceAccess,
// verifyUserAccess, // verifyUserAccess,
// verifyUserHasAction(ActionsEnum.addRoleResource),
// role.addRoleResource // role.addRoleResource
// ); // );
// authenticated.delete( // authenticated.delete(
// "/user/:userId/resource", // "/user/:userId/resource",
// verifyResourceAccess, // verifyResourceAccess,
// verifyUserAccess, // verifyUserAccess,
// verifyUserHasAction(ActionsEnum.removeRoleResource),
// role.removeRoleResource // role.removeRoleResource
// ); // );
// authenticated.put( // authenticated.put(
@ -240,6 +336,7 @@ authenticated.delete(
// verifyOrgAccess, // verifyOrgAccess,
// verifyUserAccess, // verifyUserAccess,
// verifyAdmin, // verifyAdmin,
// verifyUserHasAction(ActionsEnum.addRoleAction),
// role.addRoleAction // role.addRoleAction
// ); // );
// authenticated.delete( // authenticated.delete(
@ -247,6 +344,7 @@ authenticated.delete(
// verifyOrgAccess, // verifyOrgAccess,
// verifyUserAccess, // verifyUserAccess,
// verifyAdmin, // verifyAdmin,
// verifyUserHasAction(ActionsEnum.removeRoleAction),
// role.removeRoleAction // role.removeRoleAction
// ); // );

View file

@ -6,10 +6,9 @@ import { orgs, userOrgs } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { createAdminRole } from "@server/db/ensureActions"; import { createAdminRole } from "@server/db/ensureActions";
import config, { APP_PATH } from "@server/config"; import config from "@server/config";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const createOrgSchema = z.object({ const createOrgSchema = z.object({

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
const getOrgSchema = z.object({ const getOrgSchema = z.object({
@ -15,12 +14,12 @@ const getOrgSchema = z.object({
export type GetOrgResponse = { export type GetOrgResponse = {
org: Org; org: Org;
} };
export async function getOrg( export async function getOrg(
req: Request, req: Request,
res: Response, res: Response,
next: NextFunction, next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
const parsedParams = getOrgSchema.safeParse(req.params); const parsedParams = getOrgSchema.safeParse(req.params);
@ -28,27 +27,13 @@ export async function getOrg(
return next( return next(
createHttpError( createHttpError(
HttpCode.BAD_REQUEST, HttpCode.BAD_REQUEST,
parsedParams.error.errors.map((e) => e.message).join(", "), parsedParams.error.errors.map((e) => e.message).join(", ")
), )
); );
} }
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.getOrg,
req,
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action",
),
);
}
const org = await db const org = await db
.select() .select()
.from(orgs) .from(orgs)
@ -59,8 +44,8 @@ export async function getOrg(
return next( return next(
createHttpError( createHttpError(
HttpCode.NOT_FOUND, HttpCode.NOT_FOUND,
`Organization with ID ${orgId} not found`, `Organization with ID ${orgId} not found`
), )
); );
} }
@ -76,10 +61,7 @@ export async function getOrg(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred...",
),
); );
} }
} }

View file

@ -1,27 +1,32 @@
import { Request, Response, NextFunction } from 'express'; import { Request, Response, NextFunction } from "express";
import { z } from 'zod'; import { z } from "zod";
import { db } from '@server/db'; import { db } from "@server/db";
import { orgs } from '@server/db/schema'; import { orgs } from "@server/db/schema";
import { eq } from 'drizzle-orm'; import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from '@server/types/HttpCode'; import HttpCode from "@server/types/HttpCode";
import createHttpError from 'http-errors'; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from '@server/auth/actions'; import logger from "@server/logger";
import logger from '@server/logger'; import { fromError } from "zod-validation-error";
import { fromError } from 'zod-validation-error';
const updateOrgParamsSchema = z.object({ const updateOrgParamsSchema = z.object({
orgId: z.string() orgId: z.string(),
}); });
const updateOrgBodySchema = z.object({ const updateOrgBodySchema = z
name: z.string().min(1).max(255).optional(), .object({
domain: z.string().min(1).max(255).optional(), name: z.string().min(1).max(255).optional(),
}).refine(data => Object.keys(data).length > 0, { domain: z.string().min(1).max(255).optional(),
message: "At least one field must be provided for update" })
}); .refine((data) => Object.keys(data).length > 0, {
message: "At least one field must be provided for update",
});
export async function updateOrg(req: Request, res: Response, next: NextFunction): Promise<any> { export async function updateOrg(
req: Request,
res: Response,
next: NextFunction
): Promise<any> {
try { try {
const parsedParams = updateOrgParamsSchema.safeParse(req.params); const parsedParams = updateOrgParamsSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
@ -46,14 +51,8 @@ export async function updateOrg(req: Request, res: Response, next: NextFunction)
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
const updateData = parsedBody.data; const updateData = parsedBody.data;
const updatedOrg = await db
// Check if the user has permission to list sites .update(orgs)
const hasPermission = await checkUserActionPermission(ActionsEnum.updateOrg, req);
if (!hasPermission) {
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to perform this action'));
}
const updatedOrg = await db.update(orgs)
.set(updateData) .set(updateData)
.where(eq(orgs.orgId, orgId)) .where(eq(orgs.orgId, orgId))
.returning(); .returning();
@ -76,6 +75,8 @@ export async function updateOrg(req: Request, res: Response, next: NextFunction)
}); });
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next(createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred...")); return next(
createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
);
} }
} }

View file

@ -11,8 +11,6 @@ import {
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger";
import { eq, and } from "drizzle-orm"; import { eq, and } from "drizzle-orm";
import stoi from "@server/utils/stoi"; import stoi from "@server/utils/stoi";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -26,7 +24,6 @@ const createResourceParamsSchema = z.object({
orgId: z.string(), orgId: z.string(),
}); });
// Define Zod schema for request body validation
const createResourceSchema = z.object({ const createResourceSchema = z.object({
name: z.string().min(1).max(255), name: z.string().min(1).max(255),
subdomain: z.string().min(1).max(255).optional(), subdomain: z.string().min(1).max(255).optional(),
@ -38,7 +35,6 @@ export async function createResource(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request body
const parsedBody = createResourceSchema.safeParse(req.body); const parsedBody = createResourceSchema.safeParse(req.body);
if (!parsedBody.success) { if (!parsedBody.success) {
return next( return next(
@ -64,20 +60,6 @@ export async function createResource(
const { siteId, orgId } = parsedParams.data; const { siteId, orgId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.createResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
if (!req.userOrgRoleId) { if (!req.userOrgRoleId) {
return next( return next(
createHttpError(HttpCode.FORBIDDEN, "User does not have a role") createHttpError(HttpCode.FORBIDDEN, "User does not have a role")

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -21,7 +20,6 @@ export async function deleteResource(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request parameters
const parsedParams = deleteResourceSchema.safeParse(req.params); const parsedParams = deleteResourceSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
return next( return next(
@ -34,21 +32,6 @@ export async function deleteResource(
const { resourceId } = parsedParams.data; const { resourceId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.deleteResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Delete the resource from the database
const deletedResource = await db const deletedResource = await db
.delete(resources) .delete(resources)
.where(eq(resources.resourceId, resourceId)) .where(eq(resources.resourceId, resourceId))
@ -73,10 +56,7 @@ export async function deleteResource(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,11 +6,8 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
// Define Zod schema for request parameters validation
const getResourceSchema = z.object({ const getResourceSchema = z.object({
resourceId: z.string().transform(Number).pipe(z.number().int().positive()), resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
}); });
@ -28,7 +25,6 @@ export async function getResource(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request parameters
const parsedParams = getResourceSchema.safeParse(req.params); const parsedParams = getResourceSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
return next( return next(
@ -41,21 +37,6 @@ export async function getResource(
const { resourceId } = parsedParams.data; const { resourceId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.getResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Fetch the resource from the database
const resource = await db const resource = await db
.select() .select()
.from(resources) .from(resources)
@ -84,12 +65,8 @@ export async function getResource(
status: HttpCode.OK, status: HttpCode.OK,
}); });
} catch (error) { } catch (error) {
throw error;
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function listResourceRoles(
const { resourceId } = parsedParams.data; const { resourceId } = parsedParams.data;
// Check if the user has permission to list resource roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.listResourceRoles,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const resourceRolesList = await db const resourceRolesList = await db
.select({ .select({
roleId: roles.roleId, roleId: roles.roleId,
@ -67,10 +52,7 @@ export async function listResourceRoles(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -11,13 +11,16 @@ import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { sql, eq, or, inArray, and, count } from "drizzle-orm"; import { sql, eq, or, inArray, and, count } from "drizzle-orm";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import stoi from "@server/utils/stoi"; import stoi from "@server/utils/stoi";
const listResourcesParamsSchema = z const listResourcesParamsSchema = z
.object({ .object({
siteId: z.string().optional().transform(stoi).pipe(z.number().int().positive().optional()), siteId: z
.string()
.optional()
.transform(stoi)
.pipe(z.number().int().positive().optional()),
orgId: z.string().optional(), orgId: z.string().optional(),
}) })
.refine((data) => !!data.siteId !== !!data.orgId, { .refine((data) => !!data.siteId !== !!data.orgId, {
@ -43,7 +46,7 @@ const listResourcesSchema = z.object({
function queryResources( function queryResources(
accessibleResourceIds: number[], accessibleResourceIds: number[],
siteId?: number, siteId?: number,
orgId?: string, orgId?: string
) { ) {
if (siteId) { if (siteId) {
return db return db
@ -58,8 +61,8 @@ function queryResources(
.where( .where(
and( and(
inArray(resources.resourceId, accessibleResourceIds), inArray(resources.resourceId, accessibleResourceIds),
eq(resources.siteId, siteId), eq(resources.siteId, siteId)
), )
); );
} else if (orgId) { } else if (orgId) {
return db return db
@ -74,8 +77,8 @@ function queryResources(
.where( .where(
and( and(
inArray(resources.resourceId, accessibleResourceIds), inArray(resources.resourceId, accessibleResourceIds),
eq(resources.orgId, orgId), eq(resources.orgId, orgId)
), )
); );
} }
} }
@ -88,7 +91,7 @@ export type ListResourcesResponse = {
export async function listResources( export async function listResources(
req: Request, req: Request,
res: Response, res: Response,
next: NextFunction, next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
const parsedQuery = listResourcesSchema.safeParse(req.query); const parsedQuery = listResourcesSchema.safeParse(req.query);
@ -96,8 +99,8 @@ export async function listResources(
return next( return next(
createHttpError( createHttpError(
HttpCode.BAD_REQUEST, HttpCode.BAD_REQUEST,
parsedQuery.error.errors.map((e) => e.message).join(", "), parsedQuery.error.errors.map((e) => e.message).join(", ")
), )
); );
} }
const { limit, offset } = parsedQuery.data; const { limit, offset } = parsedQuery.data;
@ -107,36 +110,21 @@ export async function listResources(
return next( return next(
createHttpError( createHttpError(
HttpCode.BAD_REQUEST, HttpCode.BAD_REQUEST,
parsedParams.error.errors.map((e) => e.message).join(", "), parsedParams.error.errors.map((e) => e.message).join(", ")
), )
); );
} }
const { siteId, orgId } = parsedParams.data; const { siteId, orgId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.listResources,
req,
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action",
),
);
}
if (orgId && orgId !== req.userOrgId) { if (orgId && orgId !== req.userOrgId) {
return next( return next(
createHttpError( createHttpError(
HttpCode.FORBIDDEN, HttpCode.FORBIDDEN,
"User does not have access to this organization", "User does not have access to this organization"
), )
); );
} }
// Get the list of resources the user has access to
const accessibleResources = await db const accessibleResources = await db
.select({ .select({
resourceId: sql<number>`COALESCE(${userResources.resourceId}, ${roleResources.resourceId})`, resourceId: sql<number>`COALESCE(${userResources.resourceId}, ${roleResources.resourceId})`,
@ -144,17 +132,17 @@ export async function listResources(
.from(userResources) .from(userResources)
.fullJoin( .fullJoin(
roleResources, roleResources,
eq(userResources.resourceId, roleResources.resourceId), eq(userResources.resourceId, roleResources.resourceId)
) )
.where( .where(
or( or(
eq(userResources.userId, req.user!.userId), eq(userResources.userId, req.user!.userId),
eq(roleResources.roleId, req.userOrgRoleId!), eq(roleResources.roleId, req.userOrgRoleId!)
), )
); );
const accessibleResourceIds = accessibleResources.map( const accessibleResourceIds = accessibleResources.map(
(resource) => resource.resourceId, (resource) => resource.resourceId
); );
let countQuery: any = db let countQuery: any = db
@ -185,10 +173,7 @@ export async function listResources(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred...",
),
); );
} }
} }

View file

@ -6,16 +6,13 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
// Define Zod schema for request parameters validation
const updateResourceParamsSchema = z.object({ const updateResourceParamsSchema = z.object({
resourceId: z.string().transform(Number).pipe(z.number().int().positive()), resourceId: z.string().transform(Number).pipe(z.number().int().positive()),
}); });
// Define Zod schema for request body validation
const updateResourceBodySchema = z const updateResourceBodySchema = z
.object({ .object({
name: z.string().min(1).max(255).optional(), name: z.string().min(1).max(255).optional(),
@ -31,7 +28,6 @@ export async function updateResource(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request parameters
const parsedParams = updateResourceParamsSchema.safeParse(req.params); const parsedParams = updateResourceParamsSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
return next( return next(
@ -42,7 +38,6 @@ export async function updateResource(
); );
} }
// Validate request body
const parsedBody = updateResourceBodySchema.safeParse(req.body); const parsedBody = updateResourceBodySchema.safeParse(req.body);
if (!parsedBody.success) { if (!parsedBody.success) {
return next( return next(
@ -56,21 +51,6 @@ export async function updateResource(
const { resourceId } = parsedParams.data; const { resourceId } = parsedParams.data;
const updateData = parsedBody.data; const updateData = parsedBody.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.updateResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Update the resource in the database
const updatedResource = await db const updatedResource = await db
.update(resources) .update(resources)
.set(updateData) .set(updateData)
@ -96,10 +76,7 @@ export async function updateResource(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { roleActions, roles } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -48,21 +47,6 @@ export async function addRoleAction(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to add role actions
const hasPermission = await checkUserActionPermission(
ActionsEnum.addRoleAction,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Get the orgId for the role
const role = await db const role = await db
.select({ orgId: roles.orgId }) .select({ orgId: roles.orgId })
.from(roles) .from(roles)
@ -96,10 +80,7 @@ export async function addRoleAction(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { roleResources } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -47,20 +46,6 @@ export async function addRoleResource(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to add role resources
const hasPermission = await checkUserActionPermission(
ActionsEnum.addRoleResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const newRoleResource = await db const newRoleResource = await db
.insert(roleResources) .insert(roleResources)
.values({ .values({
@ -79,10 +64,7 @@ export async function addRoleResource(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { resources, roleResources, roleSites } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -48,20 +47,6 @@ export async function addRoleSite(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to add role sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.addRoleSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const newRoleSite = await db const newRoleSite = await db
.insert(roleSites) .insert(roleSites)
.values({ .values({
@ -92,10 +77,7 @@ export async function addRoleSite(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { roles } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -48,20 +47,6 @@ export async function createRole(
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
// Check if the user has permission to create roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.createRole,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const newRole = await db const newRole = await db
.insert(roles) .insert(roles)
.values({ .values({
@ -80,10 +65,7 @@ export async function createRole(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function deleteRole(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to delete roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.deleteRole,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const role = await db const role = await db
.select() .select()
.from(roles) .from(roles)
@ -94,10 +79,7 @@ export async function deleteRole(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function getRole(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to get roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.getRole,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const role = await db const role = await db
.select() .select()
.from(roles) .from(roles)
@ -71,10 +56,7 @@ export async function getRole(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function listRoleActions(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to list role actions
const hasPermission = await checkUserActionPermission(
ActionsEnum.listRoleActions,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const roleActionsList = await db const roleActionsList = await db
.select({ .select({
actionId: actions.actionId, actionId: actions.actionId,
@ -68,10 +53,7 @@ export async function listRoleActions(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function listRoleResources(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to list role resources
const hasPermission = await checkUserActionPermission(
ActionsEnum.listRoleResources,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const roleResourcesList = await db const roleResourcesList = await db
.select({ .select({
resourceId: resources.resourceId, resourceId: resources.resourceId,
@ -71,10 +56,7 @@ export async function listRoleResources(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function listRoleSites(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
// Check if the user has permission to list role sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.listRoleSites,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const roleSitesList = await db const roleSitesList = await db
.select({ .select({
siteId: sites.siteId, siteId: sites.siteId,
@ -67,10 +52,7 @@ export async function listRoleSites(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { sql, eq } from "drizzle-orm"; import { sql, eq } from "drizzle-orm";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -62,20 +61,6 @@ export async function listRoles(
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
// Check if the user has permission to list roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.listRoles,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
let baseQuery: any = db let baseQuery: any = db
.select({ .select({
roleId: roles.roleId, roleId: roles.roleId,
@ -115,10 +100,7 @@ export async function listRoles(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -48,20 +47,6 @@ export async function removeRoleAction(
const { roleId } = parsedBody.data; const { roleId } = parsedBody.data;
// Check if the user has permission to remove role actions
const hasPermission = await checkUserActionPermission(
ActionsEnum.removeRoleAction,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const deletedRoleAction = await db const deletedRoleAction = await db
.delete(roleActions) .delete(roleActions)
.where( .where(
@ -91,10 +76,7 @@ export async function removeRoleAction(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -48,20 +47,6 @@ export async function removeRoleResource(
const { roleId } = parsedBody.data; const { roleId } = parsedBody.data;
// Check if the user has permission to remove role resources
const hasPermission = await checkUserActionPermission(
ActionsEnum.removeRoleResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const deletedRoleResource = await db const deletedRoleResource = await db
.delete(roleResources) .delete(roleResources)
.where( .where(
@ -91,10 +76,7 @@ export async function removeRoleResource(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -48,20 +47,6 @@ export async function removeRoleSite(
const { roleId } = parsedBody.data; const { roleId } = parsedBody.data;
// Check if the user has permission to remove role sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.removeRoleSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const deletedRoleSite = await db const deletedRoleSite = await db
.delete(roleSites) .delete(roleSites)
.where( .where(
@ -105,10 +90,7 @@ export async function removeRoleSite(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -52,20 +51,6 @@ export async function updateRole(
const { roleId } = parsedParams.data; const { roleId } = parsedParams.data;
const updateData = parsedBody.data; const updateData = parsedBody.data;
// Check if the user has permission to update roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.updateRole,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const role = await db const role = await db
.select() .select()
.from(roles) .from(roles)
@ -115,10 +100,7 @@ export async function updateRole(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -1,17 +1,10 @@
import { Request, Response, NextFunction } from "express"; import { Request, Response, NextFunction } from "express";
import { z } from "zod"; import { z } from "zod";
import { db } from "@server/db"; import { db } from "@server/db";
import { import { roles, userSites, sites, roleSites } from "@server/db/schema";
roles,
userSites,
sites,
roleSites,
exitNodes,
} from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { eq, and } from "drizzle-orm"; import { eq, and } from "drizzle-orm";
import { getUniqueSiteName } from "@server/db/names"; import { getUniqueSiteName } from "@server/db/names";
@ -22,7 +15,6 @@ const createSiteParamsSchema = z.object({
orgId: z.string(), orgId: z.string(),
}); });
// Define Zod schema for request body validation
const createSiteSchema = z.object({ const createSiteSchema = z.object({
name: z.string().min(1).max(255), name: z.string().min(1).max(255),
exitNodeId: z.number().int().positive(), exitNodeId: z.number().int().positive(),
@ -36,9 +28,6 @@ export type CreateSiteResponse = {
siteId: number; siteId: number;
orgId: string; orgId: string;
niceId: string; niceId: string;
// niceId: string;
// subdomain: string;
// subnet: string;
}; };
export async function createSite( export async function createSite(
@ -47,7 +36,6 @@ export async function createSite(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request body
const parsedBody = createSiteSchema.safeParse(req.body); const parsedBody = createSiteSchema.safeParse(req.body);
if (!parsedBody.success) { if (!parsedBody.success) {
return next( return next(
@ -60,7 +48,6 @@ export async function createSite(
const { name, subdomain, exitNodeId, pubKey, subnet } = parsedBody.data; const { name, subdomain, exitNodeId, pubKey, subnet } = parsedBody.data;
// Validate request params
const parsedParams = createSiteParamsSchema.safeParse(req.params); const parsedParams = createSiteParamsSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
return next( return next(
@ -73,20 +60,6 @@ export async function createSite(
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.createSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission perform this action"
)
);
}
if (!req.userOrgRoleId) { if (!req.userOrgRoleId) {
return next( return next(
createHttpError(HttpCode.FORBIDDEN, "User does not have a role") createHttpError(HttpCode.FORBIDDEN, "User does not have a role")
@ -95,7 +68,6 @@ export async function createSite(
const niceId = await getUniqueSiteName(orgId); const niceId = await getUniqueSiteName(orgId);
// Create new site in the database
const [newSite] = await db const [newSite] = await db
.insert(sites) .insert(sites)
.values({ .values({
@ -144,8 +116,6 @@ export async function createSite(
niceId: newSite.niceId, niceId: newSite.niceId,
siteId: newSite.siteId, siteId: newSite.siteId,
orgId: newSite.orgId, orgId: newSite.orgId,
// subdomain: newSite.subdomain,
// subnet: newSite.subnet,
}, },
success: true, success: true,
error: false, error: false,
@ -155,10 +125,7 @@ export async function createSite(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,14 +6,12 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { deletePeer } from "../gerbil/peers"; import { deletePeer } from "../gerbil/peers";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
const API_BASE_URL = "http://localhost:3000"; const API_BASE_URL = "http://localhost:3000";
// Define Zod schema for request parameters validation
const deleteSiteSchema = z.object({ const deleteSiteSchema = z.object({
siteId: z.string().transform(Number).pipe(z.number().int().positive()), siteId: z.string().transform(Number).pipe(z.number().int().positive()),
}); });
@ -24,7 +22,6 @@ export async function deleteSite(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request parameters
const parsedParams = deleteSiteSchema.safeParse(req.params); const parsedParams = deleteSiteSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
return next( return next(
@ -37,21 +34,6 @@ export async function deleteSite(
const { siteId } = parsedParams.data; const { siteId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.deleteSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Delete the site from the database
const [deletedSite] = await db const [deletedSite] = await db
.delete(sites) .delete(sites)
.where(eq(sites.siteId, siteId)) .where(eq(sites.siteId, siteId))
@ -78,10 +60,7 @@ export async function deleteSite(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,12 +6,10 @@ import { eq, and } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import stoi from "@server/utils/stoi"; import stoi from "@server/utils/stoi";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
// Define Zod schema for request parameters validation
const getSiteSchema = z.object({ const getSiteSchema = z.object({
siteId: z siteId: z
.string() .string()
@ -36,7 +34,6 @@ export async function getSite(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request parameters
const parsedParams = getSiteSchema.safeParse(req.params); const parsedParams = getSiteSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
return next( return next(
@ -49,22 +46,7 @@ export async function getSite(
const { siteId, niceId, orgId } = parsedParams.data; const { siteId, niceId, orgId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.updateSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
let site; let site;
// Fetch the site from the database
if (siteId) { if (siteId) {
site = await db site = await db
.select() .select()
@ -107,10 +89,7 @@ export async function getSite(
} catch (error) { } catch (error) {
logger.error("Error from getSite: ", error); logger.error("Error from getSite: ", error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function listSiteRoles(
const { siteId } = parsedParams.data; const { siteId } = parsedParams.data;
// Check if the user has permission to list site roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.listSiteRoles,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const siteRolesList = await db const siteRolesList = await db
.select({ .select({
roleId: roles.roleId, roleId: roles.roleId,
@ -67,10 +52,7 @@ export async function listSiteRoles(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -1,4 +1,3 @@
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import { db } from "@server/db"; import { db } from "@server/db";
import { orgs, roleSites, sites, userSites } from "@server/db/schema"; import { orgs, roleSites, sites, userSites } from "@server/db/schema";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
@ -45,8 +44,8 @@ function querySites(orgId: string, accessibleSiteIds: number[]) {
.where( .where(
and( and(
inArray(sites.siteId, accessibleSiteIds), inArray(sites.siteId, accessibleSiteIds),
eq(sites.orgId, orgId), eq(sites.orgId, orgId)
), )
); );
} }
@ -58,7 +57,7 @@ export type ListSitesResponse = {
export async function listSites( export async function listSites(
req: Request, req: Request,
res: Response, res: Response,
next: NextFunction, next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
const parsedQuery = listSitesSchema.safeParse(req.query); const parsedQuery = listSitesSchema.safeParse(req.query);
@ -66,8 +65,8 @@ export async function listSites(
return next( return next(
createHttpError( createHttpError(
HttpCode.BAD_REQUEST, HttpCode.BAD_REQUEST,
fromError(parsedQuery.error), fromError(parsedQuery.error)
), )
); );
} }
const { limit, offset } = parsedQuery.data; const { limit, offset } = parsedQuery.data;
@ -77,32 +76,18 @@ export async function listSites(
return next( return next(
createHttpError( createHttpError(
HttpCode.BAD_REQUEST, HttpCode.BAD_REQUEST,
parsedParams.error.errors.map((e) => e.message).join(", "), parsedParams.error.errors.map((e) => e.message).join(", ")
), )
); );
} }
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.listSites,
req,
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action",
),
);
}
if (orgId && orgId !== req.userOrgId) { if (orgId && orgId !== req.userOrgId) {
return next( return next(
createHttpError( createHttpError(
HttpCode.FORBIDDEN, HttpCode.FORBIDDEN,
"User does not have access to this organization", "User does not have access to this organization"
), )
); );
} }
@ -115,8 +100,8 @@ export async function listSites(
.where( .where(
or( or(
eq(userSites.userId, req.user!.userId), eq(userSites.userId, req.user!.userId),
eq(roleSites.roleId, req.userOrgRoleId!), eq(roleSites.roleId, req.userOrgRoleId!)
), )
); );
const accessibleSiteIds = accessibleSites.map((site) => site.siteId); const accessibleSiteIds = accessibleSites.map((site) => site.siteId);
@ -128,8 +113,8 @@ export async function listSites(
.where( .where(
and( and(
inArray(sites.siteId, accessibleSiteIds), inArray(sites.siteId, accessibleSiteIds),
eq(sites.orgId, orgId), eq(sites.orgId, orgId)
), )
); );
const sitesList = await baseQuery.limit(limit).offset(offset); const sitesList = await baseQuery.limit(limit).offset(offset);
@ -152,10 +137,7 @@ export async function listSites(
}); });
} catch (error) { } catch (error) {
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred...",
),
); );
} }
} }

View file

@ -1,12 +1,10 @@
import { Request, Response, NextFunction } from "express"; import { Request, Response, NextFunction } from "express";
import { z } from "zod";
import { db } from "@server/db"; import { db } from "@server/db";
import { exitNodes, Org, orgs, sites } from "@server/db/schema"; import { exitNodes, sites } from "@server/db/schema";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { findNextAvailableCidr } from "@server/utils/ip"; import { findNextAvailableCidr } from "@server/utils/ip";
@ -26,20 +24,6 @@ export async function pickSiteDefaults(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.createSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// TODO: more intelligent way to pick the exit node // TODO: more intelligent way to pick the exit node
// make sure there is an exit node by counting the exit nodes table // make sure there is an exit node by counting the exit nodes table

View file

@ -6,16 +6,13 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
// Define Zod schema for request parameters validation
const updateSiteParamsSchema = z.object({ const updateSiteParamsSchema = z.object({
siteId: z.string().transform(Number).pipe(z.number().int().positive()), siteId: z.string().transform(Number).pipe(z.number().int().positive()),
}); });
// Define Zod schema for request body validation
const updateSiteBodySchema = z const updateSiteBodySchema = z
.object({ .object({
name: z.string().min(1).max(255).optional(), name: z.string().min(1).max(255).optional(),
@ -36,7 +33,6 @@ export async function updateSite(
next: NextFunction next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
// Validate request parameters
const parsedParams = updateSiteParamsSchema.safeParse(req.params); const parsedParams = updateSiteParamsSchema.safeParse(req.params);
if (!parsedParams.success) { if (!parsedParams.success) {
return next( return next(
@ -47,7 +43,6 @@ export async function updateSite(
); );
} }
// Validate request body
const parsedBody = updateSiteBodySchema.safeParse(req.body); const parsedBody = updateSiteBodySchema.safeParse(req.body);
if (!parsedBody.success) { if (!parsedBody.success) {
return next( return next(
@ -61,21 +56,6 @@ export async function updateSite(
const { siteId } = parsedParams.data; const { siteId } = parsedParams.data;
const updateData = parsedBody.data; const updateData = parsedBody.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.updateSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Update the site in the database
const updatedSite = await db const updatedSite = await db
.update(sites) .update(sites)
.set(updateData) .set(updateData)
@ -101,10 +81,7 @@ export async function updateSite(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { resources, sites, targets } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { addPeer } from "../gerbil/peers"; import { addPeer } from "../gerbil/peers";
import { eq, and } from "drizzle-orm"; import { eq, and } from "drizzle-orm";
@ -54,20 +53,6 @@ export async function createTarget(
const { resourceId } = parsedParams.data; const { resourceId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.createTarget,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// get the resource // get the resource
const [resource] = await db const [resource] = await db
.select({ .select({
@ -151,10 +136,7 @@ export async function createTarget(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { addPeer } from "../gerbil/peers"; import { addPeer } from "../gerbil/peers";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -33,20 +32,6 @@ export async function deleteTarget(
const { targetId } = parsedParams.data; const { targetId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.deleteTarget,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const [deletedTarget] = await db const [deletedTarget] = await db
.delete(targets) .delete(targets)
.where(eq(targets.targetId, targetId)) .where(eq(targets.targetId, targetId))
@ -125,10 +110,7 @@ export async function deleteTarget(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function getTarget(
const { targetId } = parsedParams.data; const { targetId } = parsedParams.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.getTarget,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const target = await db const target = await db
.select() .select()
.from(targets) .from(targets)
@ -71,10 +56,7 @@ export async function getTarget(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -1,6 +1,5 @@
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import { db } from "@server/db"; import { db } from "@server/db";
import { targets, resources } from "@server/db/schema"; import { targets } from "@server/db/schema";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import response from "@server/utils/response"; import response from "@server/utils/response";
import { eq, sql } from "drizzle-orm"; import { eq, sql } from "drizzle-orm";
@ -81,20 +80,6 @@ export async function listTargets(
} }
const { resourceId } = parsedParams.data; const { resourceId } = parsedParams.data;
// Check if the user has permission to list targets
const hasPermission = await checkUserActionPermission(
ActionsEnum.listTargets,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const baseQuery = queryTargets(resourceId); const baseQuery = queryTargets(resourceId);
let countQuery = db let countQuery = db
@ -123,10 +108,7 @@ export async function listTargets(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -55,20 +54,6 @@ export async function updateTarget(
const { targetId } = parsedParams.data; const { targetId } = parsedParams.data;
const updateData = parsedBody.data; const updateData = parsedBody.data;
// Check if the user has permission to list sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.updateTarget,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const updatedTarget = await db const updatedTarget = await db
.update(targets) .update(targets)
.set(updateData) .set(updateData)
@ -94,10 +79,7 @@ export async function updateTarget(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { userActions, users } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -34,21 +33,6 @@ export async function addUserAction(
const { userId, actionId, orgId } = parsedBody.data; const { userId, actionId, orgId } = parsedBody.data;
// Check if the user has permission to add user actions
const hasPermission = await checkUserActionPermission(
ActionsEnum.addUserAction,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Check if the user exists
const user = await db const user = await db
.select() .select()
.from(users) .from(users)
@ -82,10 +66,7 @@ export async function addUserAction(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { userResources } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -32,20 +31,6 @@ export async function addUserResource(
const { userId, resourceId } = parsedBody.data; const { userId, resourceId } = parsedBody.data;
// Check if the user has permission to add user resources
const hasPermission = await checkUserActionPermission(
ActionsEnum.addUserResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const newUserResource = await db const newUserResource = await db
.insert(userResources) .insert(userResources)
.values({ .values({
@ -64,10 +49,7 @@ export async function addUserResource(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -5,7 +5,6 @@ import { resources, userResources, userSites } from "@server/db/schema";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { eq } from "drizzle-orm"; import { eq } from "drizzle-orm";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -33,20 +32,6 @@ export async function addUserSite(
const { userId, siteId } = parsedBody.data; const { userId, siteId } = parsedBody.data;
// Check if the user has permission to add user sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.addUserSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const newUserSite = await db const newUserSite = await db
.insert(userSites) .insert(userSites)
.values({ .values({
@ -55,7 +40,6 @@ export async function addUserSite(
}) })
.returning(); .returning();
// Add all resources associated with the site to the user
const siteResources = await db const siteResources = await db
.select() .select()
.from(resources) .from(resources)
@ -78,10 +62,7 @@ export async function addUserSite(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
export type GetUserResponse = { export type GetUserResponse = {
@ -18,14 +17,14 @@ export type GetUserResponse = {
export async function getUser( export async function getUser(
req: Request, req: Request,
res: Response, res: Response,
next: NextFunction, next: NextFunction
): Promise<any> { ): Promise<any> {
try { try {
const userId = req.user?.userId; const userId = req.user?.userId;
if (!userId) { if (!userId) {
return next( return next(
createHttpError(HttpCode.UNAUTHORIZED, "User not found"), createHttpError(HttpCode.UNAUTHORIZED, "User not found")
); );
} }
@ -39,8 +38,8 @@ export async function getUser(
return next( return next(
createHttpError( createHttpError(
HttpCode.NOT_FOUND, HttpCode.NOT_FOUND,
`User with ID ${userId} not found`, `User with ID ${userId} not found`
), )
); );
} }
@ -60,8 +59,8 @@ export async function getUser(
return next( return next(
createHttpError( createHttpError(
HttpCode.INTERNAL_SERVER_ERROR, HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred...", "An error occurred..."
), )
); );
} }
} }

View file

@ -64,19 +64,6 @@ export async function inviteUser(
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
const { email, validHours, roleId } = parsedBody.data; const { email, validHours, roleId } = parsedBody.data;
const hasPermission = await checkUserActionPermission(
ActionsEnum.inviteUser,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const currentTime = Date.now(); const currentTime = Date.now();
const oneHourAgo = currentTime - 3600000; const oneHourAgo = currentTime - 3600000;
@ -86,7 +73,7 @@ export async function inviteUser(
inviteTracker[email].timestamps = inviteTracker[ inviteTracker[email].timestamps = inviteTracker[
email email
].timestamps.filter((timestamp) => timestamp > oneHourAgo); ].timestamps.filter((timestamp) => timestamp > oneHourAgo); // TODO: this could cause memory increase over time if the object is never deleted
if (inviteTracker[email].timestamps.length >= 3) { if (inviteTracker[email].timestamps.length >= 3) {
return next( return next(

View file

@ -6,7 +6,6 @@ import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { sql } from "drizzle-orm"; import { sql } from "drizzle-orm";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
const listUsersParamsSchema = z.object({ const listUsersParamsSchema = z.object({
@ -81,27 +80,12 @@ export async function listUsers(
const { orgId } = parsedParams.data; const { orgId } = parsedParams.data;
// Check if the user has permission to list users
const hasPermission = await checkUserActionPermission(
ActionsEnum.listUsers,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const usersWithRoles = await queryUsers( const usersWithRoles = await queryUsers(
orgId.toString(), orgId.toString(),
limit, limit,
offset offset
); );
// Count total users
const [{ count }] = await db const [{ count }] = await db
.select({ count: sql<number>`count(*)` }) .select({ count: sql<number>`count(*)` })
.from(users); .from(users);

View file

@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -49,20 +48,6 @@ export async function removeUserAction(
const { actionId, orgId } = parsedBody.data; const { actionId, orgId } = parsedBody.data;
// Check if the user has permission to remove user actions
const hasPermission = await checkUserActionPermission(
ActionsEnum.removeUserAction,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const deletedUserAction = await db const deletedUserAction = await db
.delete(userActions) .delete(userActions)
.where( .where(
@ -93,10 +78,7 @@ export async function removeUserAction(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -33,19 +32,6 @@ export async function removeUserOrg(
const { userId, orgId } = parsedParams.data; const { userId, orgId } = parsedParams.data;
const hasPermission = await checkUserActionPermission(
ActionsEnum.removeUser,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// remove the user from the userOrgs table // remove the user from the userOrgs table
await db await db
.delete(userOrgs) .delete(userOrgs)
@ -61,10 +47,7 @@ export async function removeUserOrg(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -33,20 +32,6 @@ export async function removeUserResource(
const { userId, resourceId } = parsedParams.data; const { userId, resourceId } = parsedParams.data;
// Check if the user has permission to remove user resources
const hasPermission = await checkUserActionPermission(
ActionsEnum.removeUserResource,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const deletedUserResource = await db const deletedUserResource = await db
.delete(userResources) .delete(userResources)
.where( .where(
@ -76,10 +61,7 @@ export async function removeUserResource(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { and, eq } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -48,20 +47,6 @@ export async function removeUserSite(
const { siteId } = parsedBody.data; const { siteId } = parsedBody.data;
// Check if the user has permission to remove user sites
const hasPermission = await checkUserActionPermission(
ActionsEnum.removeUserSite,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
const deletedUserSite = await db const deletedUserSite = await db
.delete(userSites) .delete(userSites)
.where( .where(
@ -105,10 +90,7 @@ export async function removeUserSite(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }

View file

@ -6,7 +6,6 @@ import { eq, and } from "drizzle-orm";
import response from "@server/utils/response"; import response from "@server/utils/response";
import HttpCode from "@server/types/HttpCode"; import HttpCode from "@server/types/HttpCode";
import createHttpError from "http-errors"; import createHttpError from "http-errors";
import { ActionsEnum, checkUserActionPermission } from "@server/auth/actions";
import logger from "@server/logger"; import logger from "@server/logger";
import { fromError } from "zod-validation-error"; import { fromError } from "zod-validation-error";
@ -34,21 +33,6 @@ export async function addUserRole(
const { userId, roleId, orgId } = parsedBody.data; const { userId, roleId, orgId } = parsedBody.data;
// Check if the user has permission to add user roles
const hasPermission = await checkUserActionPermission(
ActionsEnum.addUserRole,
req
);
if (!hasPermission) {
return next(
createHttpError(
HttpCode.FORBIDDEN,
"User does not have permission to perform this action"
)
);
}
// Check if the role exists and belongs to the specified org
const roleExists = await db const roleExists = await db
.select() .select()
.from(roles) .from(roles)
@ -80,10 +64,7 @@ export async function addUserRole(
} catch (error) { } catch (error) {
logger.error(error); logger.error(error);
return next( return next(
createHttpError( createHttpError(HttpCode.INTERNAL_SERVER_ERROR, "An error occurred")
HttpCode.INTERNAL_SERVER_ERROR,
"An error occurred..."
)
); );
} }
} }