mirror of
https://github.com/fosrl/pangolin.git
synced 2025-09-01 07:20:06 +02:00
Add actions check to all endpoints
This commit is contained in:
parent
20db6d450c
commit
81017139c5
25 changed files with 232 additions and 34 deletions
|
@ -1,10 +1,42 @@
|
||||||
import { Request } from 'express';
|
import { Request } from 'express';
|
||||||
import { db } from '@server/db';
|
import { db } from '@server/db';
|
||||||
import { userActions, roleActions, userOrgs } from '@server/db/schema';
|
import { userActions, roleActions, userOrgs } from '@server/db/schema';
|
||||||
import { and, eq, or } from 'drizzle-orm';
|
import { and, eq } from 'drizzle-orm';
|
||||||
import createHttpError from 'http-errors';
|
import createHttpError from 'http-errors';
|
||||||
import HttpCode from '@server/types/HttpCode';
|
import HttpCode from '@server/types/HttpCode';
|
||||||
|
|
||||||
|
export const ActionsEnum = {
|
||||||
|
|
||||||
|
createOrg: 1,
|
||||||
|
deleteOrg: 2,
|
||||||
|
getOrg: 3,
|
||||||
|
listOrgs: 4,
|
||||||
|
updateOrg: 5,
|
||||||
|
|
||||||
|
createSite: 6,
|
||||||
|
deleteSite: 7,
|
||||||
|
getSite: 8,
|
||||||
|
listSites: 9,
|
||||||
|
updateSite: 10,
|
||||||
|
|
||||||
|
createResource: 11,
|
||||||
|
deleteResource: 12,
|
||||||
|
getResource: 13,
|
||||||
|
listResources: 14,
|
||||||
|
updateResource: 15,
|
||||||
|
|
||||||
|
createTarget: 16,
|
||||||
|
deleteTarget: 17,
|
||||||
|
getTarget: 18,
|
||||||
|
listTargets: 19,
|
||||||
|
updateTarget: 20,
|
||||||
|
|
||||||
|
getUser: 21,
|
||||||
|
deleteUser: 22,
|
||||||
|
listUsers: 23
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
export async function checkUserActionPermission(actionId: number, req: Request): Promise<boolean> {
|
export async function checkUserActionPermission(actionId: number, req: Request): Promise<boolean> {
|
||||||
const userId = req.user?.id;
|
const userId = req.user?.id;
|
||||||
|
|
||||||
|
@ -12,11 +44,37 @@ export async function checkUserActionPermission(actionId: number, req: Request):
|
||||||
throw createHttpError(HttpCode.UNAUTHORIZED, 'User not authenticated');
|
throw createHttpError(HttpCode.UNAUTHORIZED, 'User not authenticated');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!req.userOrgId) {
|
||||||
|
throw createHttpError(HttpCode.BAD_REQUEST, 'Organization ID is required');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Check if the user has direct permission for the action
|
let userOrgRoleId = req.userOrgRoleId;
|
||||||
|
|
||||||
|
// If userOrgRoleId is not available on the request, fetch it
|
||||||
|
if (userOrgRoleId === undefined) {
|
||||||
|
const userOrgRole = await db.select()
|
||||||
|
.from(userOrgs)
|
||||||
|
.where(and(eq(userOrgs.userId, userId), eq(userOrgs.orgId, req.userOrgId)))
|
||||||
|
.limit(1);
|
||||||
|
|
||||||
|
if (userOrgRole.length === 0) {
|
||||||
|
throw createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization');
|
||||||
|
}
|
||||||
|
|
||||||
|
userOrgRoleId = userOrgRole[0].roleId;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the user has direct permission for the action in the current org
|
||||||
const userActionPermission = await db.select()
|
const userActionPermission = await db.select()
|
||||||
.from(userActions)
|
.from(userActions)
|
||||||
.where(and(eq(userActions.userId, userId), eq(userActions.actionId, actionId)))
|
.where(
|
||||||
|
and(
|
||||||
|
eq(userActions.userId, userId),
|
||||||
|
eq(userActions.actionId, actionId),
|
||||||
|
eq(userActions.orgId, req.userOrgId)
|
||||||
|
)
|
||||||
|
)
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
||||||
if (userActionPermission.length > 0) {
|
if (userActionPermission.length > 0) {
|
||||||
|
@ -24,22 +82,13 @@ export async function checkUserActionPermission(actionId: number, req: Request):
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no direct permission, check role-based permission
|
// If no direct permission, check role-based permission
|
||||||
const userOrgRoles = await db.select()
|
|
||||||
.from(userOrgs)
|
|
||||||
.where(eq(userOrgs.userId, userId));
|
|
||||||
|
|
||||||
if (userOrgRoles.length === 0) {
|
|
||||||
return false; // User doesn't belong to any organization
|
|
||||||
}
|
|
||||||
|
|
||||||
const roleIds = userOrgRoles.map(role => role.roleId);
|
|
||||||
|
|
||||||
const roleActionPermission = await db.select()
|
const roleActionPermission = await db.select()
|
||||||
.from(roleActions)
|
.from(roleActions)
|
||||||
.where(
|
.where(
|
||||||
and(
|
and(
|
||||||
eq(roleActions.actionId, actionId),
|
eq(roleActions.actionId, actionId),
|
||||||
or(...roleIds.map(roleId => eq(roleActions.roleId, roleId)))
|
eq(roleActions.roleId, userOrgRoleId),
|
||||||
|
eq(roleActions.orgId, req.userOrgId)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
.limit(1);
|
.limit(1);
|
||||||
|
|
|
@ -84,6 +84,7 @@ declare global {
|
||||||
user?: User;
|
user?: User;
|
||||||
userOrgRoleId?: number;
|
userOrgRoleId?: number;
|
||||||
userOrgId?: number;
|
userOrgId?: number;
|
||||||
|
userOrgIds?: number[];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { orgs } 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';
|
||||||
|
|
||||||
const createOrgSchema = z.object({
|
const createOrgSchema = z.object({
|
||||||
name: z.string().min(1).max(255),
|
name: z.string().min(1).max(255),
|
||||||
|
@ -25,7 +26,7 @@ export async function createOrg(req: Request, res: Response, next: NextFunction)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const userOrgIds = req.userOrgs;
|
const userOrgIds = req.userOrgIds;
|
||||||
if (userOrgIds && userOrgIds.length > MAX_ORGS) {
|
if (userOrgIds && userOrgIds.length > MAX_ORGS) {
|
||||||
return next(
|
return next(
|
||||||
createHttpError(
|
createHttpError(
|
||||||
|
@ -35,6 +36,12 @@ export async function createOrg(req: Request, res: Response, next: NextFunction)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.createOrg, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const { name, domain } = parsedBody.data;
|
const { name, domain } = parsedBody.data;
|
||||||
|
|
||||||
const newOrg = await db.insert(orgs).values({
|
const newOrg = await db.insert(orgs).values({
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const deleteOrgSchema = z.object({
|
const deleteOrgSchema = z.object({
|
||||||
orgId: z.string().transform(Number).pipe(z.number().int().positive())
|
orgId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||||
|
@ -25,6 +26,12 @@ export async function deleteOrg(req: Request, res: Response, next: NextFunction)
|
||||||
|
|
||||||
const { orgId } = parsedParams.data;
|
const { orgId } = parsedParams.data;
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.deleteOrg, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const deletedOrg = await db.delete(orgs)
|
const deletedOrg = await db.delete(orgs)
|
||||||
.where(eq(orgs.orgId, orgId))
|
.where(eq(orgs.orgId, orgId))
|
||||||
.returning();
|
.returning();
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const getOrgSchema = z.object({
|
const getOrgSchema = z.object({
|
||||||
orgId: z.string().transform(Number).pipe(z.number().int().positive())
|
orgId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||||
|
@ -25,6 +26,12 @@ export async function getOrg(req: Request, res: Response, next: NextFunction): P
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const org = await db.select()
|
const org = await db.select()
|
||||||
.from(orgs)
|
.from(orgs)
|
||||||
.where(eq(orgs.orgId, orgId))
|
.where(eq(orgs.orgId, orgId))
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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, inArray } from 'drizzle-orm';
|
import { sql, inArray } from 'drizzle-orm';
|
||||||
|
import { ActionsEnum, checkUserActionPermission } from '@server/auth/actions';
|
||||||
|
|
||||||
const listOrgsSchema = z.object({
|
const listOrgsSchema = z.object({
|
||||||
limit: z.string().optional().transform(Number).pipe(z.number().int().positive().default(10)),
|
limit: z.string().optional().transform(Number).pipe(z.number().int().positive().default(10)),
|
||||||
|
@ -26,8 +27,14 @@ export async function listOrgs(req: Request, res: Response, next: NextFunction):
|
||||||
|
|
||||||
const { limit, offset } = parsedQuery.data;
|
const { limit, offset } = parsedQuery.data;
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.listOrgs, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Use the userOrgs passed from the middleware
|
// Use the userOrgs passed from the middleware
|
||||||
const userOrgIds = req.userOrgs;
|
const userOrgIds = req.userOrgIds;
|
||||||
|
|
||||||
if (!userOrgIds || userOrgIds.length === 0) {
|
if (!userOrgIds || userOrgIds.length === 0) {
|
||||||
return res.status(HttpCode.OK).send(
|
return res.status(HttpCode.OK).send(
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const updateOrgParamsSchema = z.object({
|
const updateOrgParamsSchema = z.object({
|
||||||
orgId: z.string().transform(Number).pipe(z.number().int().positive())
|
orgId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||||
|
@ -43,6 +44,13 @@ 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;
|
||||||
|
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.updateOrg, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const updatedOrg = await db.update(orgs)
|
const updatedOrg = await db.update(orgs)
|
||||||
.set(updateData)
|
.set(updateData)
|
||||||
.where(eq(orgs.orgId, orgId))
|
.where(eq(orgs.orgId, orgId))
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { resources } 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';
|
||||||
|
|
||||||
const createResourceParamsSchema = z.object({
|
const createResourceParamsSchema = z.object({
|
||||||
siteId: z.number().int().positive(),
|
siteId: z.number().int().positive(),
|
||||||
|
@ -45,6 +46,12 @@ export async function createResource(req: Request, res: Response, next: NextFunc
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Generate a unique resourceId
|
// Generate a unique resourceId
|
||||||
const resourceId = "subdomain" // TODO: create the subdomain here
|
const resourceId = "subdomain" // TODO: create the subdomain here
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
// Define Zod schema for request parameters validation
|
// Define Zod schema for request parameters validation
|
||||||
const deleteResourceSchema = z.object({
|
const deleteResourceSchema = z.object({
|
||||||
|
@ -27,6 +28,12 @@ export async function deleteResource(req: Request, res: Response, next: NextFunc
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Delete the resource from the database
|
// Delete the resource from the database
|
||||||
const deletedResource = await db.delete(resources)
|
const deletedResource = await db.delete(resources)
|
||||||
.where(eq(resources.resourceId, resourceId))
|
.where(eq(resources.resourceId, resourceId))
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
// Define Zod schema for request parameters validation
|
// Define Zod schema for request parameters validation
|
||||||
const getResourceSchema = z.object({
|
const getResourceSchema = z.object({
|
||||||
|
@ -27,6 +28,12 @@ export async function getResource(req: Request, res: Response, next: NextFunctio
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch the resource from the database
|
// Fetch the resource from the database
|
||||||
const resource = await db.select()
|
const resource = await db.select()
|
||||||
.from(resources)
|
.from(resources)
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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, and, or, inArray } from 'drizzle-orm';
|
import { sql, eq, and, or, inArray } from 'drizzle-orm';
|
||||||
|
import { ActionsEnum, checkUserActionPermission } from '@server/auth/actions';
|
||||||
|
|
||||||
const listResourcesParamsSchema = z.object({
|
const listResourcesParamsSchema = z.object({
|
||||||
siteId: z.coerce.number().int().positive().optional(),
|
siteId: z.coerce.number().int().positive().optional(),
|
||||||
|
@ -26,13 +27,6 @@ interface RequestWithOrgAndRole extends Request {
|
||||||
|
|
||||||
export async function listResources(req: RequestWithOrgAndRole, res: Response, next: NextFunction): Promise<any> {
|
export async function listResources(req: RequestWithOrgAndRole, res: Response, next: NextFunction): Promise<any> {
|
||||||
try {
|
try {
|
||||||
// Check if the user has permission to list resources
|
|
||||||
// const LIST_RESOURCES_ACTION_ID = 3; // Assume 3 is the action ID for listing resources
|
|
||||||
// const hasPermission = await checkUserActionPermission(LIST_RESOURCES_ACTION_ID, req);
|
|
||||||
// if (!hasPermission) {
|
|
||||||
// return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list resources'));
|
|
||||||
// }
|
|
||||||
|
|
||||||
const parsedQuery = listResourcesSchema.safeParse(req.query);
|
const parsedQuery = listResourcesSchema.safeParse(req.query);
|
||||||
if (!parsedQuery.success) {
|
if (!parsedQuery.success) {
|
||||||
return next(createHttpError(HttpCode.BAD_REQUEST, parsedQuery.error.errors.map(e => e.message).join(', ')));
|
return next(createHttpError(HttpCode.BAD_REQUEST, parsedQuery.error.errors.map(e => e.message).join(', ')));
|
||||||
|
@ -45,6 +39,12 @@ export async function listResources(req: RequestWithOrgAndRole, res: Response, n
|
||||||
}
|
}
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
if (orgId && orgId !== req.orgId) {
|
if (orgId && orgId !== req.orgId) {
|
||||||
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
// Define Zod schema for request parameters validation
|
// Define Zod schema for request parameters validation
|
||||||
const updateResourceParamsSchema = z.object({
|
const updateResourceParamsSchema = z.object({
|
||||||
|
@ -47,6 +48,12 @@ export async function updateResource(req: Request, res: Response, next: NextFunc
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Update the resource in the database
|
// Update the resource in the database
|
||||||
const updatedResource = await db.update(resources)
|
const updatedResource = await db.update(resources)
|
||||||
.set(updateData)
|
.set(updateData)
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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 fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
|
import { ActionsEnum, checkUserActionPermission } from '@server/auth/actions';
|
||||||
|
|
||||||
const API_BASE_URL = "http://localhost:3000";
|
const API_BASE_URL = "http://localhost:3000";
|
||||||
|
|
||||||
|
@ -33,7 +34,7 @@ export async function createSite(req: Request, res: Response, next: NextFunction
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const { name, subdomain, pubKey, subnet } = parsedBody.data;
|
const { name, subdomain, pubKey, subnet } = parsedBody.data;
|
||||||
|
|
||||||
// Validate request params
|
// Validate request params
|
||||||
|
@ -49,6 +50,12 @@ export async function createSite(req: Request, res: Response, next: NextFunction
|
||||||
|
|
||||||
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 to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Create new site in the database
|
// Create new site in the database
|
||||||
const newSite = await db.insert(sites).values({
|
const newSite = await db.insert(sites).values({
|
||||||
orgId,
|
orgId,
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
|
|
||||||
const API_BASE_URL = "http://localhost:3000";
|
const API_BASE_URL = "http://localhost:3000";
|
||||||
|
@ -27,9 +28,15 @@ export async function deleteSite(req: Request, res: Response, next: NextFunction
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Delete the site from the database
|
// Delete the site from the database
|
||||||
const deletedSite = await db.delete(sites)
|
const deletedSite = await db.delete(sites)
|
||||||
.where(eq(sites.siteId, siteId))
|
.where(eq(sites.siteId, siteId))
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
// Define Zod schema for request parameters validation
|
// Define Zod schema for request parameters validation
|
||||||
const getSiteSchema = z.object({
|
const getSiteSchema = z.object({
|
||||||
|
@ -27,6 +28,12 @@ export async function getSite(req: Request, res: Response, next: NextFunction):
|
||||||
|
|
||||||
const { siteId } = parsedParams.data;
|
const { siteId } = 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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Fetch the site from the database
|
// Fetch the site from the database
|
||||||
const site = await db.select()
|
const site = await db.select()
|
||||||
.from(sites)
|
.from(sites)
|
||||||
|
|
|
@ -6,7 +6,7 @@ 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, and, or, inArray } from 'drizzle-orm';
|
import { sql, eq, and, or, inArray } from 'drizzle-orm';
|
||||||
// import { checkUserActionPermission } from './checkUserActionPermission'; // Import the function we created earlier
|
import { ActionsEnum, checkUserActionPermission } from '@server/auth/actions';
|
||||||
|
|
||||||
const listSitesParamsSchema = z.object({
|
const listSitesParamsSchema = z.object({
|
||||||
orgId: z.string().optional().transform(Number).pipe(z.number().int().positive()),
|
orgId: z.string().optional().transform(Number).pipe(z.number().int().positive()),
|
||||||
|
@ -19,25 +19,25 @@ const listSitesSchema = z.object({
|
||||||
|
|
||||||
export async function listSites(req: Request, res: Response, next: NextFunction): Promise<any> {
|
export async function listSites(req: Request, res: Response, next: NextFunction): Promise<any> {
|
||||||
try {
|
try {
|
||||||
// Check if the user has permission to list sites
|
|
||||||
// const LIST_SITES_ACTION_ID = 1; // Assume 1 is the action ID for listing sites
|
|
||||||
// const hasPermission = await checkUserActionPermission(LIST_SITES_ACTION_ID, req);
|
|
||||||
// if (!hasPermission) {
|
|
||||||
// return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
|
||||||
// }
|
|
||||||
|
|
||||||
const parsedQuery = listSitesSchema.safeParse(req.query);
|
const parsedQuery = listSitesSchema.safeParse(req.query);
|
||||||
if (!parsedQuery.success) {
|
if (!parsedQuery.success) {
|
||||||
return next(createHttpError(HttpCode.BAD_REQUEST, parsedQuery.error.errors.map(e => e.message).join(', ')));
|
return next(createHttpError(HttpCode.BAD_REQUEST, parsedQuery.error.errors.map(e => e.message).join(', ')));
|
||||||
}
|
}
|
||||||
const { limit, offset } = parsedQuery.data;
|
const { limit, offset } = parsedQuery.data;
|
||||||
|
|
||||||
|
|
||||||
const parsedParams = listSitesParamsSchema.safeParse(req.params);
|
const parsedParams = listSitesParamsSchema.safeParse(req.params);
|
||||||
if (!parsedParams.success) {
|
if (!parsedParams.success) {
|
||||||
return next(createHttpError(HttpCode.BAD_REQUEST, parsedParams.error.errors.map(e => e.message).join(', ')));
|
return next(createHttpError(HttpCode.BAD_REQUEST, 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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
if (orgId && orgId !== req.userOrgId) {
|
if (orgId && orgId !== req.userOrgId) {
|
||||||
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have access to this organization'));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
// Define Zod schema for request parameters validation
|
// Define Zod schema for request parameters validation
|
||||||
const updateSiteParamsSchema = z.object({
|
const updateSiteParamsSchema = z.object({
|
||||||
|
@ -52,6 +53,12 @@ export async function updateSite(req: Request, res: Response, next: NextFunction
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
// Update the site in the database
|
// Update the site in the database
|
||||||
const updatedSite = await db.update(sites)
|
const updatedSite = await db.update(sites)
|
||||||
.set(updateData)
|
.set(updateData)
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { 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';
|
||||||
|
|
||||||
const createTargetParamsSchema = z.object({
|
const createTargetParamsSchema = z.object({
|
||||||
resourceId: z.string().uuid(),
|
resourceId: z.string().uuid(),
|
||||||
|
@ -44,6 +45,12 @@ export async function createTarget(req: Request, res: Response, next: NextFuncti
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const newTarget = await db.insert(targets).values({
|
const newTarget = await db.insert(targets).values({
|
||||||
resourceId,
|
resourceId,
|
||||||
...targetData
|
...targetData
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const deleteTargetSchema = z.object({
|
const deleteTargetSchema = z.object({
|
||||||
targetId: z.string().transform(Number).pipe(z.number().int().positive())
|
targetId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||||
|
@ -25,6 +26,12 @@ export async function deleteTarget(req: Request, res: Response, next: NextFuncti
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const deletedTarget = await db.delete(targets)
|
const deletedTarget = await db.delete(targets)
|
||||||
.where(eq(targets.targetId, targetId))
|
.where(eq(targets.targetId, targetId))
|
||||||
.returning();
|
.returning();
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const getTargetSchema = z.object({
|
const getTargetSchema = z.object({
|
||||||
targetId: z.string().transform(Number).pipe(z.number().int().positive())
|
targetId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||||
|
@ -25,6 +26,12 @@ export async function getTarget(req: Request, res: Response, next: NextFunction)
|
||||||
|
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const target = await db.select()
|
const target = await db.select()
|
||||||
.from(targets)
|
.from(targets)
|
||||||
.where(eq(targets.targetId, targetId))
|
.where(eq(targets.targetId, targetId))
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const listTargetsParamsSchema = z.object({
|
const listTargetsParamsSchema = z.object({
|
||||||
resourceId: z.string().optional()
|
resourceId: z.string().optional()
|
||||||
|
@ -41,6 +42,12 @@ export async function listTargets(req: Request, res: Response, next: NextFunctio
|
||||||
}
|
}
|
||||||
|
|
||||||
const { resourceId } = parsedParams.data;
|
const { resourceId } = parsedParams.data;
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.listTargets, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
let baseQuery: any = db
|
let baseQuery: any = db
|
||||||
.select({
|
.select({
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const updateTargetParamsSchema = z.object({
|
const updateTargetParamsSchema = z.object({
|
||||||
targetId: z.string().transform(Number).pipe(z.number().int().positive())
|
targetId: z.string().transform(Number).pipe(z.number().int().positive())
|
||||||
|
@ -46,6 +47,12 @@ export async function updateTarget(req: Request, res: Response, next: NextFuncti
|
||||||
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 list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const updatedTarget = await db.update(targets)
|
const updatedTarget = await db.update(targets)
|
||||||
.set(updateData)
|
.set(updateData)
|
||||||
.where(eq(targets.targetId, targetId))
|
.where(eq(targets.targetId, targetId))
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const deleteUserSchema = z.object({
|
const deleteUserSchema = z.object({
|
||||||
userId: z.string().uuid()
|
userId: z.string().uuid()
|
||||||
|
@ -25,6 +26,12 @@ export async function deleteUser(req: Request, res: Response, next: NextFunction
|
||||||
|
|
||||||
const { userId } = parsedParams.data;
|
const { userId } = parsedParams.data;
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.deleteUser, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const deletedUser = await db.delete(users)
|
const deletedUser = await db.delete(users)
|
||||||
.where(eq(users.id, userId))
|
.where(eq(users.id, userId))
|
||||||
.returning();
|
.returning();
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const getUserSchema = z.object({
|
const getUserSchema = z.object({
|
||||||
userId: z.string().uuid()
|
userId: z.string().uuid()
|
||||||
|
@ -25,6 +26,12 @@ export async function getUser(req: Request, res: Response, next: NextFunction):
|
||||||
|
|
||||||
const { userId } = parsedParams.data;
|
const { userId } = parsedParams.data;
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.getUser, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const user = await db.select()
|
const user = await db.select()
|
||||||
.from(users)
|
.from(users)
|
||||||
.where(eq(users.id, userId))
|
.where(eq(users.id, userId))
|
||||||
|
|
|
@ -6,6 +6,7 @@ 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';
|
||||||
|
|
||||||
const listUsersSchema = z.object({
|
const listUsersSchema = z.object({
|
||||||
limit: z.string().optional().transform(Number).pipe(z.number().int().positive().default(10)),
|
limit: z.string().optional().transform(Number).pipe(z.number().int().positive().default(10)),
|
||||||
|
@ -26,6 +27,12 @@ export async function listUsers(req: Request, res: Response, next: NextFunction)
|
||||||
|
|
||||||
const { limit, offset } = parsedQuery.data;
|
const { limit, offset } = parsedQuery.data;
|
||||||
|
|
||||||
|
// Check if the user has permission to list sites
|
||||||
|
const hasPermission = await checkUserActionPermission(ActionsEnum.listUsers, req);
|
||||||
|
if (!hasPermission) {
|
||||||
|
return next(createHttpError(HttpCode.FORBIDDEN, 'User does not have permission to list sites'));
|
||||||
|
}
|
||||||
|
|
||||||
const usersList = await db.select()
|
const usersList = await db.select()
|
||||||
.from(users)
|
.from(users)
|
||||||
.limit(limit)
|
.limit(limit)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue