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