first commit
This commit is contained in:
93
src/middleware/validation.middleware.ts
Normal file
93
src/middleware/validation.middleware.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { Request, Response, NextFunction } from 'express';
|
||||
import { z } from 'zod';
|
||||
import type { ApiResponse, GetInfoRequest } from '../types/index.js';
|
||||
|
||||
/**
|
||||
* Validation schema for /api/getinfo endpoint
|
||||
*/
|
||||
const getInfoSchema = z.object({
|
||||
url: z.string().url('Invalid URL format').refine((url) => {
|
||||
// Validate Netflix URL
|
||||
try {
|
||||
const parsedUrl = new URL(url);
|
||||
const validHosts = [
|
||||
'www.netflix.com',
|
||||
'netflix.com',
|
||||
'www.netflix.com.tr',
|
||||
'netflix.com.tr',
|
||||
];
|
||||
const hasTitlePath = /\/title\/\d+/.test(url);
|
||||
return validHosts.includes(parsedUrl.hostname) && hasTitlePath;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}, 'URL must be a valid Netflix title URL (e.g., https://www.netflix.com/tr/title/81616256)'),
|
||||
});
|
||||
|
||||
/**
|
||||
* Validate request body for /api/getinfo
|
||||
*/
|
||||
export function validateGetInfo(
|
||||
req: Request,
|
||||
res: Response,
|
||||
next: NextFunction
|
||||
): void {
|
||||
const result = getInfoSchema.safeParse(req.body);
|
||||
|
||||
if (!result.success) {
|
||||
const errors = result.error.issues.map((issue) => ({
|
||||
field: issue.path.join('.'),
|
||||
message: issue.message,
|
||||
}));
|
||||
|
||||
const response: ApiResponse<never> = {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'VALIDATION_ERROR',
|
||||
message: 'Invalid request parameters',
|
||||
details: { errors },
|
||||
},
|
||||
};
|
||||
|
||||
res.status(400).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
// Attach validated data to request
|
||||
(req as Request & { validated: GetInfoRequest }).validated = result.data;
|
||||
next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic validation middleware factory
|
||||
*/
|
||||
export function validateBody<T extends z.ZodType>(
|
||||
schema: T
|
||||
): (req: Request, res: Response, next: NextFunction) => void {
|
||||
return (req, res, next) => {
|
||||
const result = schema.safeParse(req.body);
|
||||
|
||||
if (!result.success) {
|
||||
const errors = result.error.issues.map((issue) => ({
|
||||
field: issue.path.join('.'),
|
||||
message: issue.message,
|
||||
}));
|
||||
|
||||
const response: ApiResponse<never> = {
|
||||
success: false,
|
||||
error: {
|
||||
code: 'VALIDATION_ERROR',
|
||||
message: 'Invalid request parameters',
|
||||
details: { errors },
|
||||
},
|
||||
};
|
||||
|
||||
res.status(400).json(response);
|
||||
return;
|
||||
}
|
||||
|
||||
next();
|
||||
};
|
||||
}
|
||||
|
||||
export default validateGetInfo;
|
||||
Reference in New Issue
Block a user