Commit f8b76737 authored by ThinhNC's avatar ThinhNC

fix(api,validation): standardize CrawlScheduleController envelope and enforce...

fix(api,validation): standardize CrawlScheduleController envelope and enforce validateParams on all route identifiers
parent 2a7f8a5f
This diff is collapsed.
...@@ -3,10 +3,14 @@ import { ApiKeyController } from "./api-key.controller"; ...@@ -3,10 +3,14 @@ import { ApiKeyController } from "./api-key.controller";
import { authMiddleware } from "../../middlewares/auth.middleware"; import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant"; import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validate } from "../../middlewares/validate.middleware"; import {
validate,
validateParams,
} from "../../middlewares/validate.middleware";
import { import {
createApiKeySchema, createApiKeySchema,
updateApiKeyStatusSchema, updateApiKeyStatusSchema,
apiKeyParamsSchema,
} from "./api-key.validation"; } from "./api-key.validation";
const router = Router(); const router = Router();
...@@ -29,6 +33,7 @@ router.patch( ...@@ -29,6 +33,7 @@ router.patch(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.API_KEYS_UPDATE), requirePermission(PERMISSIONS.API_KEYS_UPDATE),
validateParams(apiKeyParamsSchema),
validate(updateApiKeyStatusSchema), validate(updateApiKeyStatusSchema),
controller.setActive, controller.setActive,
); );
...@@ -36,6 +41,7 @@ router.delete( ...@@ -36,6 +41,7 @@ router.delete(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.API_KEYS_DELETE), requirePermission(PERMISSIONS.API_KEYS_DELETE),
validateParams(apiKeyParamsSchema),
controller.revoke, controller.revoke,
); );
......
...@@ -24,3 +24,7 @@ export const updateApiKeyStatusSchema = z.object({ ...@@ -24,3 +24,7 @@ export const updateApiKeyStatusSchema = z.object({
invalid_type_error: "API Key status must be a boolean", invalid_type_error: "API Key status must be a boolean",
}), }),
}); });
export const apiKeyParamsSchema = z.object({
id: z.string().uuid("Invalid API key ID format"),
});
import { Router } from "express"; import { Router } from "express";
import { CrawlJobController } from "./crawl-job.controller"; import { CrawlJobController } from "./crawl-job.controller";
import { apiKeyOrAuthMiddleware } from "../../middlewares/api-key.middleware"; import { apiKeyOrAuthMiddleware } from "../../middlewares/api-key.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware"; import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import { import {
createCrawlJobSchema, createCrawlJobSchema,
createExportSchema, createExportSchema,
...@@ -9,6 +13,7 @@ import { ...@@ -9,6 +13,7 @@ import {
getAssetsQuerySchema, getAssetsQuerySchema,
jobLogsQuerySchema, jobLogsQuerySchema,
diffQuerySchema, diffQuerySchema,
crawlJobParamsSchema,
} from "./crawl-job.validation"; } from "./crawl-job.validation";
import { crawlPageQuerySchema } from "../crawl-pages/crawl-page.validation"; import { crawlPageQuerySchema } from "../crawl-pages/crawl-page.validation";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
...@@ -37,24 +42,28 @@ router.get( ...@@ -37,24 +42,28 @@ router.get(
"/:id", "/:id",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
controller.findById, controller.findById,
); );
router.delete( router.delete(
"/:id", "/:id",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_DELETE), requirePermission(PERMISSIONS.CRAWL_JOBS_DELETE),
validateParams(crawlJobParamsSchema),
controller.delete, controller.delete,
); );
router.post( router.post(
"/:id/rerun", "/:id/rerun",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_RETRY), requirePermission(PERMISSIONS.CRAWL_JOBS_RETRY),
validateParams(crawlJobParamsSchema),
controller.rerun, controller.rerun,
); );
router.get( router.get(
"/:id/logs", "/:id/logs",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(jobLogsQuerySchema), validateQuery(jobLogsQuerySchema),
controller.getLogs, controller.getLogs,
); );
...@@ -62,18 +71,21 @@ router.get( ...@@ -62,18 +71,21 @@ router.get(
"/:id/events", "/:id/events",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
controller.streamEvents, controller.streamEvents,
); );
router.post( router.post(
"/:id/cancel", "/:id/cancel",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_CANCEL), requirePermission(PERMISSIONS.CRAWL_JOBS_CANCEL),
validateParams(crawlJobParamsSchema),
controller.cancel, controller.cancel,
); );
router.get( router.get(
"/:id/pages", "/:id/pages",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(crawlPageQuerySchema), validateQuery(crawlPageQuerySchema),
controller.getPages, controller.getPages,
); );
...@@ -81,6 +93,7 @@ router.get( ...@@ -81,6 +93,7 @@ router.get(
"/:id/pages/preview", "/:id/pages/preview",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(crawlPageQuerySchema), validateQuery(crawlPageQuerySchema),
controller.getPagesPreview, controller.getPagesPreview,
); );
...@@ -88,12 +101,14 @@ router.get( ...@@ -88,12 +101,14 @@ router.get(
"/:id/exports", "/:id/exports",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.EXPORTS_READ), requirePermission(PERMISSIONS.EXPORTS_READ),
validateParams(crawlJobParamsSchema),
controller.getExports, controller.getExports,
); );
router.post( router.post(
"/:id/exports", "/:id/exports",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.EXPORTS_CREATE), requirePermission(PERMISSIONS.EXPORTS_CREATE),
validateParams(crawlJobParamsSchema),
validate(createExportSchema), validate(createExportSchema),
(req, res, next) => { (req, res, next) => {
controller.createExport(req, res, next); controller.createExport(req, res, next);
...@@ -103,12 +118,14 @@ router.get( ...@@ -103,12 +118,14 @@ router.get(
"/:id/download", "/:id/download",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.EXPORTS_DOWNLOAD), requirePermission(PERMISSIONS.EXPORTS_DOWNLOAD),
validateParams(crawlJobParamsSchema),
controller.download, controller.download,
); );
router.get( router.get(
"/:id/assets", "/:id/assets",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(getAssetsQuerySchema), validateQuery(getAssetsQuerySchema),
controller.getAssets, controller.getAssets,
); );
...@@ -116,6 +133,7 @@ router.get( ...@@ -116,6 +133,7 @@ router.get(
"/:id/diff", "/:id/diff",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(diffQuerySchema), validateQuery(diffQuerySchema),
controller.getDiff, controller.getDiff,
); );
...@@ -123,6 +141,7 @@ router.get( ...@@ -123,6 +141,7 @@ router.get(
"/:id/diff/download", "/:id/diff/download",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_JOBS_READ), requirePermission(PERMISSIONS.CRAWL_JOBS_READ),
validateParams(crawlJobParamsSchema),
validateQuery(diffQuerySchema), validateQuery(diffQuerySchema),
controller.downloadDiff, controller.downloadDiff,
); );
......
...@@ -86,3 +86,7 @@ export const diffQuerySchema = z.object({ ...@@ -86,3 +86,7 @@ export const diffQuerySchema = z.object({
.uuid("Invalid compareWithJobId format") .uuid("Invalid compareWithJobId format")
.optional(), .optional(),
}); });
export const crawlJobParamsSchema = z.object({
id: z.string().uuid("Invalid job ID format"),
});
...@@ -13,6 +13,7 @@ export class CrawlScheduleController { ...@@ -13,6 +13,7 @@ export class CrawlScheduleController {
req.body, req.body,
); );
res.status(201).json({ res.status(201).json({
success: true,
message: "Crawl schedule created successfully", message: "Crawl schedule created successfully",
data: schedule, data: schedule,
}); });
...@@ -28,7 +29,10 @@ export class CrawlScheduleController { ...@@ -28,7 +29,10 @@ export class CrawlScheduleController {
req.user!.role, req.user!.role,
req.query as unknown as CrawlScheduleQueryDto, req.query as unknown as CrawlScheduleQueryDto,
); );
res.json(result); res.json({
success: true,
data: result,
});
} catch (error) { } catch (error) {
next(error); next(error);
} }
...@@ -41,7 +45,10 @@ export class CrawlScheduleController { ...@@ -41,7 +45,10 @@ export class CrawlScheduleController {
req.user!.role, req.user!.role,
req.params.id, req.params.id,
); );
res.json(schedule); res.json({
success: true,
data: schedule,
});
} catch (error) { } catch (error) {
next(error); next(error);
} }
...@@ -56,6 +63,7 @@ export class CrawlScheduleController { ...@@ -56,6 +63,7 @@ export class CrawlScheduleController {
req.body, req.body,
); );
res.json({ res.json({
success: true,
message: "Crawl schedule updated successfully", message: "Crawl schedule updated successfully",
data: updated, data: updated,
}); });
...@@ -68,6 +76,7 @@ export class CrawlScheduleController { ...@@ -68,6 +76,7 @@ export class CrawlScheduleController {
try { try {
await this.service.delete(req.user!.id, req.user!.role, req.params.id); await this.service.delete(req.user!.id, req.user!.role, req.params.id);
res.json({ res.json({
success: true,
message: "Crawl schedule deleted successfully", message: "Crawl schedule deleted successfully",
}); });
} catch (error) { } catch (error) {
...@@ -83,6 +92,7 @@ export class CrawlScheduleController { ...@@ -83,6 +92,7 @@ export class CrawlScheduleController {
req.params.id, req.params.id,
); );
res.status(201).json({ res.status(201).json({
success: true,
message: "Scheduled crawl triggered successfully", message: "Scheduled crawl triggered successfully",
data: job, data: job,
}); });
...@@ -104,7 +114,10 @@ export class CrawlScheduleController { ...@@ -104,7 +114,10 @@ export class CrawlScheduleController {
page, page,
limit, limit,
); );
res.json(history); res.json({
success: true,
data: history,
});
} catch (error) { } catch (error) {
next(error); next(error);
} }
......
import { Router } from "express"; import { Router } from "express";
import { CrawlScheduleController } from "./crawl-schedule.controller"; import { CrawlScheduleController } from "./crawl-schedule.controller";
import { apiKeyOrAuthMiddleware } from "../../middlewares/api-key.middleware"; import { apiKeyOrAuthMiddleware } from "../../middlewares/api-key.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware"; import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import { import {
createCrawlScheduleSchema, createCrawlScheduleSchema,
updateCrawlScheduleSchema, updateCrawlScheduleSchema,
crawlScheduleQuerySchema, crawlScheduleQuerySchema,
crawlScheduleHistoryQuerySchema, crawlScheduleHistoryQuerySchema,
crawlScheduleParamsSchema,
} from "./crawl-schedule.validation"; } from "./crawl-schedule.validation";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant"; import { PERMISSIONS } from "../../common/constants/permission.constant";
...@@ -34,6 +39,7 @@ router.get( ...@@ -34,6 +39,7 @@ router.get(
"/:id", "/:id",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_READ), requirePermission(PERMISSIONS.CRAWL_SCHEDULES_READ),
validateParams(crawlScheduleParamsSchema),
controller.findById, controller.findById,
); );
...@@ -41,6 +47,7 @@ router.patch( ...@@ -41,6 +47,7 @@ router.patch(
"/:id", "/:id",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_UPDATE), requirePermission(PERMISSIONS.CRAWL_SCHEDULES_UPDATE),
validateParams(crawlScheduleParamsSchema),
validate(updateCrawlScheduleSchema), validate(updateCrawlScheduleSchema),
controller.update, controller.update,
); );
...@@ -49,6 +56,7 @@ router.delete( ...@@ -49,6 +56,7 @@ router.delete(
"/:id", "/:id",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_DELETE), requirePermission(PERMISSIONS.CRAWL_SCHEDULES_DELETE),
validateParams(crawlScheduleParamsSchema),
controller.delete, controller.delete,
); );
...@@ -56,6 +64,7 @@ router.post( ...@@ -56,6 +64,7 @@ router.post(
"/:id/run", "/:id/run",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_RUN), requirePermission(PERMISSIONS.CRAWL_SCHEDULES_RUN),
validateParams(crawlScheduleParamsSchema),
controller.triggerRun, controller.triggerRun,
); );
...@@ -63,6 +72,7 @@ router.get( ...@@ -63,6 +72,7 @@ router.get(
"/:id/history", "/:id/history",
apiKeyOrAuthMiddleware, apiKeyOrAuthMiddleware,
requirePermission(PERMISSIONS.CRAWL_SCHEDULES_READ), requirePermission(PERMISSIONS.CRAWL_SCHEDULES_READ),
validateParams(crawlScheduleParamsSchema),
validateQuery(crawlScheduleHistoryQuerySchema), validateQuery(crawlScheduleHistoryQuerySchema),
controller.getHistory, controller.getHistory,
); );
......
...@@ -111,3 +111,7 @@ export const crawlScheduleHistoryQuerySchema = z.object({ ...@@ -111,3 +111,7 @@ export const crawlScheduleHistoryQuerySchema = z.object({
page: z.coerce.number().int().min(1).default(1), page: z.coerce.number().int().min(1).default(1),
limit: z.coerce.number().int().min(1).max(100).default(20), limit: z.coerce.number().int().min(1).max(100).default(20),
}); });
export const crawlScheduleParamsSchema = z.object({
id: z.string().uuid("Invalid schedule ID format"),
});
...@@ -3,10 +3,14 @@ import { ExtractionTemplateController } from "./extraction-template.controller"; ...@@ -3,10 +3,14 @@ import { ExtractionTemplateController } from "./extraction-template.controller";
import { authMiddleware } from "../../middlewares/auth.middleware"; import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant"; import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validate } from "../../middlewares/validate.middleware"; import {
validate,
validateParams,
} from "../../middlewares/validate.middleware";
import { import {
createExtractionTemplateSchema, createExtractionTemplateSchema,
updateExtractionTemplateSchema, updateExtractionTemplateSchema,
extractionTemplateParamsSchema,
} from "./extraction-template.validation"; } from "./extraction-template.validation";
const router = Router(); const router = Router();
...@@ -28,17 +32,20 @@ router.get( ...@@ -28,17 +32,20 @@ router.get(
router.get( router.get(
"/:id", "/:id",
requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_READ), requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_READ),
validateParams(extractionTemplateParamsSchema),
controller.findById, controller.findById,
); );
router.patch( router.patch(
"/:id", "/:id",
requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_UPDATE), requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_UPDATE),
validateParams(extractionTemplateParamsSchema),
validate(updateExtractionTemplateSchema), validate(updateExtractionTemplateSchema),
controller.update, controller.update,
); );
router.delete( router.delete(
"/:id", "/:id",
requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_DELETE), requirePermission(PERMISSIONS.EXTRACTION_TEMPLATES_DELETE),
validateParams(extractionTemplateParamsSchema),
controller.delete, controller.delete,
); );
......
...@@ -27,3 +27,7 @@ export const updateExtractionTemplateSchema = z.object({ ...@@ -27,3 +27,7 @@ export const updateExtractionTemplateSchema = z.object({
name: z.string().min(1).optional(), name: z.string().min(1).optional(),
fields: z.array(extractionFieldSchema).min(1).optional(), fields: z.array(extractionFieldSchema).min(1).optional(),
}); });
export const extractionTemplateParamsSchema = z.object({
id: z.string().uuid("Invalid template ID format"),
});
...@@ -3,6 +3,8 @@ import { PermissionController } from "./permission.controller"; ...@@ -3,6 +3,8 @@ import { PermissionController } from "./permission.controller";
import { authMiddleware } from "../../middlewares/auth.middleware"; import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant"; import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validateParams } from "../../middlewares/validate.middleware";
import { permissionParamsSchema } from "./permission.validation";
const router = Router(); const router = Router();
const controller = new PermissionController(); const controller = new PermissionController();
...@@ -18,6 +20,7 @@ router.get( ...@@ -18,6 +20,7 @@ router.get(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.PERMISSIONS_READ), requirePermission(PERMISSIONS.PERMISSIONS_READ),
validateParams(permissionParamsSchema),
controller.findById, controller.findById,
); );
......
import { z } from "zod";
export const permissionParamsSchema = z.object({
id: z.string().uuid("Invalid permission ID format"),
});
...@@ -2,12 +2,17 @@ import { Router } from "express"; ...@@ -2,12 +2,17 @@ import { Router } from "express";
import { RoleController } from "./role.controller"; import { RoleController } from "./role.controller";
import { authMiddleware } from "../../middlewares/auth.middleware"; import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware"; import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import { import {
createRoleSchema, createRoleSchema,
updateRoleSchema, updateRoleSchema,
assignRolePermissionsSchema, assignRolePermissionsSchema,
listRolesQuerySchema, listRolesQuerySchema,
roleParamsSchema,
} from "./role.validation"; } from "./role.validation";
import { PERMISSIONS } from "../../common/constants/permission.constant"; import { PERMISSIONS } from "../../common/constants/permission.constant";
...@@ -26,6 +31,7 @@ router.get( ...@@ -26,6 +31,7 @@ router.get(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.ROLES_READ), requirePermission(PERMISSIONS.ROLES_READ),
validateParams(roleParamsSchema),
controller.findById, controller.findById,
); );
...@@ -41,6 +47,7 @@ router.patch( ...@@ -41,6 +47,7 @@ router.patch(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.ROLES_UPDATE), requirePermission(PERMISSIONS.ROLES_UPDATE),
validateParams(roleParamsSchema),
validate(updateRoleSchema), validate(updateRoleSchema),
controller.update, controller.update,
); );
...@@ -49,6 +56,7 @@ router.delete( ...@@ -49,6 +56,7 @@ router.delete(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.ROLES_DELETE), requirePermission(PERMISSIONS.ROLES_DELETE),
validateParams(roleParamsSchema),
controller.delete, controller.delete,
); );
...@@ -56,6 +64,7 @@ router.get( ...@@ -56,6 +64,7 @@ router.get(
"/:id/permissions", "/:id/permissions",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.ROLES_PERMISSIONS_READ), requirePermission(PERMISSIONS.ROLES_PERMISSIONS_READ),
validateParams(roleParamsSchema),
controller.getRolePermissions, controller.getRolePermissions,
); );
...@@ -63,6 +72,7 @@ router.put( ...@@ -63,6 +72,7 @@ router.put(
"/:id/permissions", "/:id/permissions",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.ROLES_PERMISSIONS_ASSIGN), requirePermission(PERMISSIONS.ROLES_PERMISSIONS_ASSIGN),
validateParams(roleParamsSchema),
validate(assignRolePermissionsSchema), validate(assignRolePermissionsSchema),
controller.setRolePermissions, controller.setRolePermissions,
); );
...@@ -71,6 +81,7 @@ router.get( ...@@ -71,6 +81,7 @@ router.get(
"/:id/users", "/:id/users",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.ROLES_READ), requirePermission(PERMISSIONS.ROLES_READ),
validateParams(roleParamsSchema),
controller.getRoleUsers, controller.getRoleUsers,
); );
......
...@@ -67,3 +67,12 @@ export const listRolesQuerySchema = z.object({ ...@@ -67,3 +67,12 @@ export const listRolesQuerySchema = z.object({
) )
.optional(), .optional(),
}); });
export const roleParamsSchema = z.object({
id: z.string().uuid("Invalid role ID format"),
});
export const rolePermissionParamsSchema = z.object({
id: z.string().uuid("Invalid role ID format"),
permissionId: z.string().uuid("Invalid permission ID format"),
});
...@@ -2,12 +2,18 @@ import { Router } from "express"; ...@@ -2,12 +2,18 @@ import { Router } from "express";
import { UserController } from "./user.controller"; import { UserController } from "./user.controller";
import { authMiddleware } from "../../middlewares/auth.middleware"; import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
import { validate, validateQuery } from "../../middlewares/validate.middleware"; import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import { import {
createUserSchema, createUserSchema,
updateUserSchema, updateUserSchema,
listUsersQuerySchema, listUsersQuerySchema,
assignUserRolesSchema, assignUserRolesSchema,
userParamsSchema,
userRoleAssignmentParamsSchema,
} from "./user.validation"; } from "./user.validation";
import { PERMISSIONS } from "../../common/constants/permission.constant"; import { PERMISSIONS } from "../../common/constants/permission.constant";
...@@ -26,6 +32,7 @@ router.get( ...@@ -26,6 +32,7 @@ router.get(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.USERS_READ), requirePermission(PERMISSIONS.USERS_READ),
validateParams(userParamsSchema),
controller.findById, controller.findById,
); );
...@@ -44,6 +51,7 @@ router.put( ...@@ -44,6 +51,7 @@ router.put(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.USERS_UPDATE), requirePermission(PERMISSIONS.USERS_UPDATE),
validateParams(userParamsSchema),
validate(updateUserSchema), validate(updateUserSchema),
(req, res, next) => { (req, res, next) => {
// #swagger.requestBody = { schema: { $ref: '#/components/schemas/UpdateUserRequest' } } // #swagger.requestBody = { schema: { $ref: '#/components/schemas/UpdateUserRequest' } }
...@@ -55,6 +63,7 @@ router.delete( ...@@ -55,6 +63,7 @@ router.delete(
"/:id", "/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.USERS_DELETE), requirePermission(PERMISSIONS.USERS_DELETE),
validateParams(userParamsSchema),
controller.delete, controller.delete,
); );
...@@ -63,6 +72,7 @@ router.get( ...@@ -63,6 +72,7 @@ router.get(
"/:id/roles", "/:id/roles",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_READ), requirePermission(PERMISSIONS.USERS_ROLES_READ),
validateParams(userParamsSchema),
controller.getUserRoles, controller.getUserRoles,
); );
...@@ -70,6 +80,7 @@ router.put( ...@@ -70,6 +80,7 @@ router.put(
"/:id/roles", "/:id/roles",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN), requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN),
validateParams(userParamsSchema),
validate(assignUserRolesSchema), validate(assignUserRolesSchema),
controller.assignRoles, controller.assignRoles,
); );
...@@ -78,6 +89,7 @@ router.post( ...@@ -78,6 +89,7 @@ router.post(
"/:id/roles/:roleId", "/:id/roles/:roleId",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN), requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN),
validateParams(userRoleAssignmentParamsSchema),
controller.assignRole, controller.assignRole,
); );
...@@ -85,6 +97,7 @@ router.delete( ...@@ -85,6 +97,7 @@ router.delete(
"/:id/roles/:roleId", "/:id/roles/:roleId",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN), requirePermission(PERMISSIONS.USERS_ROLES_ASSIGN),
validateParams(userRoleAssignmentParamsSchema),
controller.revokeRole, controller.revokeRole,
); );
......
...@@ -47,3 +47,12 @@ export const assignUserRolesSchema = z.object({ ...@@ -47,3 +47,12 @@ export const assignUserRolesSchema = z.object({
required_error: "roleIds array is required", required_error: "roleIds array is required",
}), }),
}); });
export const userParamsSchema = z.object({
id: z.string().uuid("Invalid user ID format"),
});
export const userRoleAssignmentParamsSchema = z.object({
id: z.string().uuid("Invalid user ID format"),
roleId: z.string().uuid("Invalid role ID format"),
});
...@@ -3,11 +3,16 @@ import { WebhookController } from "./webhook.controller"; ...@@ -3,11 +3,16 @@ import { WebhookController } from "./webhook.controller";
import { authMiddleware } from "../../middlewares/auth.middleware"; import { authMiddleware } from "../../middlewares/auth.middleware";
import { requirePermission } from "../../middlewares/permission.middleware"; import { requirePermission } from "../../middlewares/permission.middleware";
import { PERMISSIONS } from "../../common/constants/permission.constant"; import { PERMISSIONS } from "../../common/constants/permission.constant";
import { validate, validateQuery } from "../../middlewares/validate.middleware"; import {
validate,
validateQuery,
validateParams,
} from "../../middlewares/validate.middleware";
import { import {
createWebhookConfigSchema, createWebhookConfigSchema,
updateWebhookConfigSchema, updateWebhookConfigSchema,
listWebhookDeliveriesQuerySchema, listWebhookDeliveriesQuerySchema,
webhookParamsSchema,
} from "./webhook.validation"; } from "./webhook.validation";
const router = Router(); const router = Router();
...@@ -30,6 +35,7 @@ router.patch( ...@@ -30,6 +35,7 @@ router.patch(
"/configs/:id", "/configs/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_UPDATE), requirePermission(PERMISSIONS.WEBHOOKS_UPDATE),
validateParams(webhookParamsSchema),
validate(updateWebhookConfigSchema), validate(updateWebhookConfigSchema),
controller.updateConfig, controller.updateConfig,
); );
...@@ -37,12 +43,14 @@ router.delete( ...@@ -37,12 +43,14 @@ router.delete(
"/configs/:id", "/configs/:id",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_DELETE), requirePermission(PERMISSIONS.WEBHOOKS_DELETE),
validateParams(webhookParamsSchema),
controller.deleteConfig, controller.deleteConfig,
); );
router.post( router.post(
"/configs/:id/test", "/configs/:id/test",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_TEST), requirePermission(PERMISSIONS.WEBHOOKS_TEST),
validateParams(webhookParamsSchema),
controller.testConfig, controller.testConfig,
); );
router.get( router.get(
...@@ -56,6 +64,7 @@ router.post( ...@@ -56,6 +64,7 @@ router.post(
"/deliveries/:id/redeliver", "/deliveries/:id/redeliver",
authMiddleware, authMiddleware,
requirePermission(PERMISSIONS.WEBHOOKS_UPDATE), requirePermission(PERMISSIONS.WEBHOOKS_UPDATE),
validateParams(webhookParamsSchema),
controller.redeliver, controller.redeliver,
); );
......
...@@ -41,3 +41,7 @@ export const listWebhookDeliveriesQuerySchema = z.object({ ...@@ -41,3 +41,7 @@ export const listWebhookDeliveriesQuerySchema = z.object({
page: z.coerce.number().int().min(1).default(1), page: z.coerce.number().int().min(1).default(1),
limit: z.coerce.number().int().min(1).max(100).default(20), limit: z.coerce.number().int().min(1).max(100).default(20),
}); });
export const webhookParamsSchema = z.object({
id: z.string().uuid("Invalid webhook ID format"),
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment