Skip to content

Commit e46243a

Browse files
committed
fix: validate mailing list script input with shared zod schema (CM-1318)
Signed-off-by: Uroš Marolt <uros@marolt.me>
1 parent 11332de commit e46243a

2 files changed

Lines changed: 11 additions & 3 deletions

File tree

backend/src/api/integration/helpers/mailingListAuthenticate.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const isSafeSourceUrl = (sourceUrl: string): boolean => {
2929
}
3030
}
3131

32-
const bodySchema = z.object({
32+
export const bodySchema = z.object({
3333
lists: z
3434
.array(
3535
z.object({

backend/src/bin/scripts/create-mailing-list-integration.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@ import * as fs from 'fs'
77

88
import { DEFAULT_TENANT_ID, generateUUIDv1 } from '@crowd/common'
99

10+
import { bodySchema } from '@/api/integration/helpers/mailingListAuthenticate'
1011
import SegmentRepository from '@/database/repositories/segmentRepository'
1112
import SequelizeRepository from '@/database/repositories/sequelizeRepository'
1213
import IntegrationService from '@/services/integrationService'
14+
import { validateOrThrow } from '@/utils/validation'
1315

1416
const options = [
1517
{
@@ -67,14 +69,20 @@ if (parameters.help || !parameters.file) {
6769
process.exit(1)
6870
}
6971

70-
let lists
72+
let parsed: unknown
7173
try {
72-
lists = JSON.parse(fileContents)
74+
parsed = JSON.parse(fileContents)
7375
} catch (err) {
7476
console.error(`File at ${parameters.file} is not valid JSON: ${(err as Error).message}`)
7577
process.exit(1)
7678
}
7779

80+
// Same validation as the connect API endpoint (mailingListAuthenticate.ts),
81+
// so a malformed file (non-array, missing fields, duplicate/non-https
82+
// sourceUrl) fails fast here instead of reaching IntegrationService with
83+
// whatever shape the file happened to contain.
84+
const { lists } = validateOrThrow(bodySchema, { lists: parsed })
85+
7886
const repoOptions = await SequelizeRepository.getDefaultIRepositoryOptions()
7987
repoOptions.currentTenant = { id: DEFAULT_TENANT_ID }
8088
;(repoOptions as unknown as { requestId: string }).requestId = generateUUIDv1()

0 commit comments

Comments
 (0)