fix: tighten project api validation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -10,8 +10,16 @@ import {
|
|||||||
const router = Router();
|
const router = Router();
|
||||||
|
|
||||||
const projectIdSchema = z.string().transform((val, ctx) => {
|
const projectIdSchema = z.string().transform((val, ctx) => {
|
||||||
|
// Strict integer validation: only digits, no leading zeros (except "0" itself)
|
||||||
|
if (!/^\d+$/.test(val) || (val.length > 1 && val[0] === '0')) {
|
||||||
|
ctx.addIssue({
|
||||||
|
code: z.ZodIssueCode.custom,
|
||||||
|
message: 'Project ID must be a positive integer',
|
||||||
|
});
|
||||||
|
return z.NEVER;
|
||||||
|
}
|
||||||
const parsed = parseInt(val, 10);
|
const parsed = parseInt(val, 10);
|
||||||
if (isNaN(parsed) || parsed <= 0) {
|
if (parsed <= 0) {
|
||||||
ctx.addIssue({
|
ctx.addIssue({
|
||||||
code: z.ZodIssueCode.custom,
|
code: z.ZodIssueCode.custom,
|
||||||
message: 'Project ID must be a positive integer',
|
message: 'Project ID must be a positive integer',
|
||||||
@@ -22,7 +30,11 @@ const projectIdSchema = z.string().transform((val, ctx) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const createProjectSchema = z.object({
|
const createProjectSchema = z.object({
|
||||||
name: z.string().min(1, 'Project name is required'),
|
name: z.string()
|
||||||
|
.min(1, 'Project name is required')
|
||||||
|
.refine((val) => val.trim().length > 0, {
|
||||||
|
message: 'Project name cannot be only whitespace',
|
||||||
|
}),
|
||||||
description: z.string().optional(),
|
description: z.string().optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -166,4 +166,26 @@ describe('Platform Projects API', () => {
|
|||||||
expect(response.body).toHaveProperty('error');
|
expect(response.body).toHaveProperty('error');
|
||||||
expect(typeof response.body.error).toBe('string');
|
expect(typeof response.body.error).toBe('string');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('rejects whitespace-only project name', async () => {
|
||||||
|
const response = await request(app)
|
||||||
|
.post('/v1/platform/projects')
|
||||||
|
.set('Authorization', `Bearer ${platformToken}`)
|
||||||
|
.send({ name: ' ' })
|
||||||
|
.expect(400);
|
||||||
|
|
||||||
|
expect(response.body).toHaveProperty('error');
|
||||||
|
expect(typeof response.body.error).toBe('string');
|
||||||
|
expect(response.body.error).toContain('whitespace');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('rejects malformed project ID like 123abc', async () => {
|
||||||
|
const response = await request(app)
|
||||||
|
.get('/v1/platform/projects/123abc')
|
||||||
|
.set('Authorization', `Bearer ${platformToken}`)
|
||||||
|
.expect(400);
|
||||||
|
|
||||||
|
expect(response.body).toHaveProperty('error');
|
||||||
|
expect(typeof response.body.error).toBe('string');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user