fix(zoho): P0/P1 criticals — credential check, response validation, timeout, null normalization (Neo N1)
This commit is contained in:
parent
a963dc4dcc
commit
5b0a509e70
|
|
@ -208,8 +208,8 @@ const supportSchema = z.object({
|
|||
const ZOHO_ENABLED = process.env.ZOHO_ENABLED === 'true'
|
||||
const ZOHO_API_DOMAIN = process.env.ZOHO_API_DOMAIN || 'https://www.zohoapis.com'
|
||||
const ZOHO_CLIENT_ID = process.env.ZOHO_CLIENT_ID || ''
|
||||
const ZOHO_CLIENT_SECRET = process.env.ZOHO_CLIENT_SECRET || ''
|
||||
const ZOHO_REFRESH_TOKEN = process.env.ZOHO_REFRESH_TOKEN || ''
|
||||
const ZOHO_CLIENT_SECRET = process.env.ZOHO_CLIENT_SECRET || null
|
||||
const ZOHO_REFRESH_TOKEN = process.env.ZOHO_REFRESH_TOKEN || null
|
||||
const ZOHO_REDIRECT_URI = process.env.ZOHO_REDIRECT_URI || ''
|
||||
|
||||
// In-memory access token cache
|
||||
|
|
@ -253,6 +253,12 @@ async function getZohoAccessToken() {
|
|||
async function forwardToZoho(leadData) {
|
||||
if (!ZOHO_ENABLED) return
|
||||
|
||||
// Issue #2: Short-circuit if Zoho credentials are missing
|
||||
if (!ZOHO_CLIENT_SECRET || !ZOHO_REFRESH_TOKEN) {
|
||||
log.warn('[Zoho] Skipping forwarding - ZOHO_CLIENT_SECRET or ZOHO_REFRESH_TOKEN not configured')
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
const accessToken = await getZohoAccessToken()
|
||||
if (!accessToken) {
|
||||
|
|
@ -270,26 +276,43 @@ async function forwardToZoho(leadData) {
|
|||
Phone: leadData.phone || '',
|
||||
Zip_Code: leadData.zip || '',
|
||||
Description: leadData.message || '',
|
||||
Service_Interest: leadData.service_interest || '',
|
||||
Service_Interest: leadData.service_interest || null,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Zoho-oauthtoken ${accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
})
|
||||
// Issue #5: Add timeout using AbortController
|
||||
const controller = new AbortController()
|
||||
const timeoutId = setTimeout(() => controller.abort(), 10000) // 10 second timeout
|
||||
|
||||
try {
|
||||
const response = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Authorization': `Zoho-oauthtoken ${accessToken}`,
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify(payload),
|
||||
signal: controller.signal,
|
||||
})
|
||||
|
||||
// Issue #3: Check response.ok before processing
|
||||
if (!response.ok) {
|
||||
const text = await response.text()
|
||||
log.error(`[Zoho] Lead forwarding failed (${response.status}):`, text)
|
||||
return
|
||||
}
|
||||
|
||||
if (response.ok) {
|
||||
const result = await response.json()
|
||||
log.info('[Zoho] Lead forwarded successfully:', result.data?.[0]?.details?.id || 'no id returned')
|
||||
} else {
|
||||
const text = await response.text()
|
||||
log.error(`[Zoho] Lead forwarding failed (${response.status}):`, text)
|
||||
} catch (fetchErr) {
|
||||
if (fetchErr.name === 'AbortError') {
|
||||
log.warn('[Zoho] Lead forwarding timed out after 10 seconds')
|
||||
} else {
|
||||
log.error('[Zoho] Forwarding error:', fetchErr.message)
|
||||
}
|
||||
} finally {
|
||||
clearTimeout(timeoutId)
|
||||
}
|
||||
} catch (err) {
|
||||
log.error('[Zoho] Forwarding error:', err.message)
|
||||
|
|
|
|||
Loading…
Reference in New Issue