mirror of
https://github.com/fosrl/pangolin.git
synced 2025-07-25 21:25:06 +02:00
move action permission check to middleware
This commit is contained in:
parent
03051878ef
commit
372e51c0a5
48 changed files with 266 additions and 936 deletions
36
server/routers/auth/verifyUserHasAction.ts
Normal file
36
server/routers/auth/verifyUserHasAction.ts
Normal 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"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
|
@ -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
|
||||||
// );
|
// );
|
||||||
|
|
||||||
|
|
|
@ -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({
|
||||||
|
|
|
@ -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...",
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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...",
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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...",
|
|
||||||
),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
||||||
),
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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(
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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..."
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue