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_ENABLED = process.env.ZOHO_ENABLED === 'true'
|
||||||
const ZOHO_API_DOMAIN = process.env.ZOHO_API_DOMAIN || 'https://www.zohoapis.com'
|
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_ID = process.env.ZOHO_CLIENT_ID || ''
|
||||||
const ZOHO_CLIENT_SECRET = process.env.ZOHO_CLIENT_SECRET || ''
|
const ZOHO_CLIENT_SECRET = process.env.ZOHO_CLIENT_SECRET || null
|
||||||
const ZOHO_REFRESH_TOKEN = process.env.ZOHO_REFRESH_TOKEN || ''
|
const ZOHO_REFRESH_TOKEN = process.env.ZOHO_REFRESH_TOKEN || null
|
||||||
const ZOHO_REDIRECT_URI = process.env.ZOHO_REDIRECT_URI || ''
|
const ZOHO_REDIRECT_URI = process.env.ZOHO_REDIRECT_URI || ''
|
||||||
|
|
||||||
// In-memory access token cache
|
// In-memory access token cache
|
||||||
|
|
@ -253,6 +253,12 @@ async function getZohoAccessToken() {
|
||||||
async function forwardToZoho(leadData) {
|
async function forwardToZoho(leadData) {
|
||||||
if (!ZOHO_ENABLED) return
|
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 {
|
try {
|
||||||
const accessToken = await getZohoAccessToken()
|
const accessToken = await getZohoAccessToken()
|
||||||
if (!accessToken) {
|
if (!accessToken) {
|
||||||
|
|
@ -270,26 +276,43 @@ async function forwardToZoho(leadData) {
|
||||||
Phone: leadData.phone || '',
|
Phone: leadData.phone || '',
|
||||||
Zip_Code: leadData.zip || '',
|
Zip_Code: leadData.zip || '',
|
||||||
Description: leadData.message || '',
|
Description: leadData.message || '',
|
||||||
Service_Interest: leadData.service_interest || '',
|
Service_Interest: leadData.service_interest || null,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
||||||
const response = await fetch(url, {
|
// Issue #5: Add timeout using AbortController
|
||||||
method: 'POST',
|
const controller = new AbortController()
|
||||||
headers: {
|
const timeoutId = setTimeout(() => controller.abort(), 10000) // 10 second timeout
|
||||||
'Authorization': `Zoho-oauthtoken ${accessToken}`,
|
|
||||||
'Content-Type': 'application/json',
|
try {
|
||||||
},
|
const response = await fetch(url, {
|
||||||
body: JSON.stringify(payload),
|
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()
|
const result = await response.json()
|
||||||
log.info('[Zoho] Lead forwarded successfully:', result.data?.[0]?.details?.id || 'no id returned')
|
log.info('[Zoho] Lead forwarded successfully:', result.data?.[0]?.details?.id || 'no id returned')
|
||||||
} else {
|
} catch (fetchErr) {
|
||||||
const text = await response.text()
|
if (fetchErr.name === 'AbortError') {
|
||||||
log.error(`[Zoho] Lead forwarding failed (${response.status}):`, text)
|
log.warn('[Zoho] Lead forwarding timed out after 10 seconds')
|
||||||
|
} else {
|
||||||
|
log.error('[Zoho] Forwarding error:', fetchErr.message)
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
clearTimeout(timeoutId)
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
log.error('[Zoho] Forwarding error:', err.message)
|
log.error('[Zoho] Forwarding error:', err.message)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue