fix: add input validation and safe JSON parsing across 13 CLIs

Add missing parameter validation to prevent /path/undefined API calls:
- dub: require --url for links create
- google-search-console: require --sitemap-url for sitemaps submit
- kit: validate IDs and emails for subscribers, forms, sequences, tags, broadcasts
- mailchimp: validate IDs for lists get, campaigns get/create/send, members add, reports get
- resend: validate --from/--to/--subject for send, audience/contact IDs for contacts
- rewardful: validate IDs for affiliates get/update, commissions get, links create
- semrush: require --domain/--phrase for all domain and keyword commands
- sendgrid: validate --from/--to/--subject for send, campaign IDs, email for validate

Wrap bare JSON.parse() calls in try/catch for user-provided JSON:
- dub (--links), ga4 (--params), kit (--fields x4), mixpanel (--properties x2),
  onesignal (--filters), paddle (--scheduled-change, --items x2),
  resend (--emails, --variables x2), segment (--properties, --traits, --events),
  sendgrid (--template-data)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Corey Haines
2026-02-17 22:44:06 -08:00
parent 51bdf2f6b3
commit 8eaff5e29f
13 changed files with 103 additions and 20 deletions
+6
View File
@@ -75,6 +75,7 @@ async function main() {
case 'domain':
switch (sub) {
case 'overview': {
if (!args.domain) { result = { error: '--domain required' }; break }
const params = new URLSearchParams({
type: 'domain_ranks',
export_columns: 'Db,Dn,Rk,Or,Ot,Oc,Ad,At,Ac',
@@ -84,6 +85,7 @@ async function main() {
break
}
case 'organic': {
if (!args.domain) { result = { error: '--domain required' }; break }
const params = new URLSearchParams({
type: 'domain_organic',
export_columns: 'Ph,Po,Pp,Pd,Nq,Cp,Ur,Tr,Tc,Co,Nr',
@@ -95,6 +97,7 @@ async function main() {
break
}
case 'competitors': {
if (!args.domain) { result = { error: '--domain required' }; break }
const params = new URLSearchParams({
type: 'domain_organic_organic',
export_columns: 'Dn,Cr,Np,Or,Ot,Oc,Ad',
@@ -113,6 +116,7 @@ async function main() {
case 'keywords':
switch (sub) {
case 'overview': {
if (!args.phrase) { result = { error: '--phrase required' }; break }
const params = new URLSearchParams({
type: 'phrase_all',
export_columns: 'Ph,Nq,Cp,Co,Nr',
@@ -123,6 +127,7 @@ async function main() {
break
}
case 'related': {
if (!args.phrase) { result = { error: '--phrase required' }; break }
const params = new URLSearchParams({
type: 'phrase_related',
export_columns: 'Ph,Nq,Cp,Co,Nr,Td',
@@ -134,6 +139,7 @@ async function main() {
break
}
case 'difficulty': {
if (!args.phrase) { result = { error: '--phrase required' }; break }
const params = new URLSearchParams({
type: 'phrase_kdi',
export_columns: 'Ph,Kd',