fix: make local provider robust to random input

This commit is contained in:
Mythie
2024-05-17 12:42:23 +10:00
parent 2e41ecf825
commit 002dc0fdae
3 changed files with 20 additions and 8 deletions

View File

@ -1,5 +1,4 @@
import { jobsClient } from '@documenso/lib/jobs/client';
import '@documenso/lib/jobs/definitions';
export const config = {
maxDuration: 300,

View File

@ -5,16 +5,14 @@ import type { Json } from './json';
export const ZTriggerJobOptionsSchema = z.object({
id: z.string().optional(),
name: z.string(),
payload: z.any().refine((x) => x !== undefined, { message: 'payload is required' }),
payload: z.unknown().refine((x) => x !== undefined, { message: 'payload is required' }),
timestamp: z.number().optional(),
});
// The Omit is a temporary workaround for a "bug" in the zod library
// @see: https://github.com/colinhacks/zod/issues/2966
export type TriggerJobOptions = Omit<z.infer<typeof ZTriggerJobOptionsSchema>, 'payload'> & {
// Don't tell the feds
// eslint-disable-next-line @typescript-eslint/no-explicit-any
payload: any;
payload: unknown;
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any

View File

@ -9,7 +9,12 @@ import { BackgroundJobStatus, Prisma } from '@documenso/prisma/client';
import { NEXT_PUBLIC_WEBAPP_URL } from '../../constants/app';
import { sign } from '../../server-only/crypto/sign';
import { verify } from '../../server-only/crypto/verify';
import type { JobDefinition, JobRunIO, TriggerJobOptions } from './_internal/job';
import {
type JobDefinition,
type JobRunIO,
type TriggerJobOptions,
ZTriggerJobOptionsSchema,
} from './_internal/job';
import type { Json } from './_internal/json';
import { BaseJobProvider } from './base';
@ -59,7 +64,8 @@ export class LocalJobProvider extends BaseJobProvider {
jobId: job.id,
name: job.name,
version: job.version,
payload: options.payload,
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
payload: options.payload as Prisma.InputJsonValue,
},
});
@ -80,7 +86,16 @@ export class LocalJobProvider extends BaseJobProvider {
const isRetry = req.headers['x-job-retry'] !== undefined;
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
const options = (await json(req)) as TriggerJobOptions;
const options = await json(req)
.then(async (data) => ZTriggerJobOptionsSchema.parseAsync(data))
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
.then((data) => data as TriggerJobOptions)
.catch(() => null);
if (!options) {
res.status(400).send('Bad request');
return;
}
const definition = this._jobDefinitions[options.name];