Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.demo
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ OID4VP_AUTH_REQUEST_PROOF_REQUEST_EXPIRY=3600
APP_JSON_BODY_SIZE=5mb
APP_URL_ENCODED_BODY_SIZE=5mb

# Webhook awaited expiry is in milliseconds
WEBHOOK_TIMEOUT_MS=10000

API_KEY=supersecret-that-too-16chars
UPDATE_JWT_SECRET=false
Expand Down
12 changes: 10 additions & 2 deletions src/events/WebhookEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,24 @@

import fetch from 'node-fetch'

const DEFAULT_TIMEOUT = 5000;

export const sendWebhookEvent = async (
webhookUrl: string,
body: Record<string, unknown>,
logger: Logger,
timeoutMs = 5000,
timeoutMs?: number,
): Promise<void> => {
Comment on lines +5 to 12
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Validate resolved timeout before using it.

Line 11 currently trusts parsed env values too much; a negative WEBHOOK_TIMEOUT_MS will cause near-immediate aborts. Since several event modules call this function without an explicit timeout, this can break webhook delivery globally.

💡 Proposed fix
-const DEFAULT_TIMEOUT = 5000;
+const DEFAULT_TIMEOUT = 5000

 export const sendWebhookEvent = async (
   webhookUrl: string,
   body: Record<string, unknown>,
   logger: Logger,
-  timeoutMs: number = parseInt(process.env.WEBHOOK_TIMEOUT_MS || '', 10) || DEFAULT_TIMEOUT,
+  timeoutMs?: number,
 ): Promise<void> => {
-
-  console.log(`Sending webhook event to ${webhookUrl} with timeout of ${timeoutMs}ms`)
+  const envTimeout = parseInt(process.env.WEBHOOK_TIMEOUT_MS ?? '', 10)
+  const candidateTimeout = timeoutMs ?? envTimeout
+  const resolvedTimeout = candidateTimeout > 0 ? candidateTimeout : DEFAULT_TIMEOUT
   // Abort the webhook send events if the request hangs-in for >5 secs
   // This can avoid failure of services due to bad webhook listners
   const controller = new AbortController()
-  const timeout = setTimeout(() => controller.abort(), timeoutMs)
+  const timeout = setTimeout(() => controller.abort(), resolvedTimeout)

Also applies to: 18-18

🧰 Tools
🪛 ESLint

[error] 5-5: Delete ;

(prettier/prettier)

🪛 GitHub Check: SonarCloud Code Analysis

[warning] 11-11: Prefer Number.parseInt over parseInt.

See more on https://sonarcloud.io/project/issues?id=credebl_afj-controller&issues=AZ3PACJiNgPe1EPLZpl-&open=AZ3PACJiNgPe1EPLZpl-&pullRequest=365

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/events/WebhookEvent.ts` around lines 5 - 12, The timeout resolution in
sendWebhookEvent trusts parseInt(process.env.WEBHOOK_TIMEOUT_MS) and can yield
negative or NaN values; validate the resolved timeoutMs inside sendWebhookEvent
(or at point of defaulting) to ensure it's a positive integer and if not, fall
back to DEFAULT_TIMEOUT. Specifically, after obtaining timeoutMs (from the
parameter or parsed env), check that it's a finite number >= 0 (or > 0 per
desired semantics) and replace invalid values with DEFAULT_TIMEOUT before using
it for the request/abort logic so negative env values cannot cause immediate
aborts.


const envTimeout = parseInt(process.env.WEBHOOK_TIMEOUT_MS ?? '', 10)

Check warning on line 14 in src/events/WebhookEvent.ts

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Prefer `Number.parseInt` over `parseInt`.

See more on https://sonarcloud.io/project/issues?id=credebl_afj-controller&issues=AZ3S4vW6DMkdZNrQgV8N&open=AZ3S4vW6DMkdZNrQgV8N&pullRequest=365
const candidateTimeout = timeoutMs ?? envTimeout
const resolvedTimeout = candidateTimeout > 0 ? candidateTimeout : DEFAULT_TIMEOUT

logger.info(`Sending webhook event to ${webhookUrl} with timeout of ${resolvedTimeout}ms`)
// Abort the webhook send events if the request hangs-in for >5 secs
// This can avoid failure of services due to bad webhook listners
const controller = new AbortController()
const timeout = setTimeout(() => controller.abort(), timeoutMs)
const timeout = setTimeout(() => controller.abort(), resolvedTimeout)

try {
await fetch(webhookUrl, {
Expand Down