Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
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
6 changes: 5 additions & 1 deletion src/events/WebhookEvent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

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 = parseInt(process.env.WEBHOOK_TIMEOUT_MS || '', 10) || DEFAULT_TIMEOUT,

Check warning on line 11 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=AZ3PACJiNgPe1EPLZpl-&open=AZ3PACJiNgPe1EPLZpl-&pullRequest=365
): 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.


console.log(`Sending webhook event to ${webhookUrl} with timeout of ${timeoutMs}ms`)

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

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Verify which logger levels are used in the repo so replacement matches existing conventions.
rg -n --type=ts -C2 '\blogger\.(trace|debug|info|warn|error)\('

# Inspect local logger-related typings/usages to confirm available methods.
rg -n --type=ts -C2 'type Logger|interface Logger|from .+Logger'

Repository: credebl/agent-controller

Length of output: 12863


🏁 Script executed:

cat -n src/events/WebhookEvent.ts

Repository: credebl/agent-controller

Length of output: 1597


Replace console.log with logger.info.

Line 14 uses direct console logging which triggers no-console linting and can leak webhook URLs into unmanaged logs. Replace with the injected logger for structured, policy-controlled logging:

Replace with:
logger.info(`Sending webhook event to ${webhookUrl} with timeout of ${timeoutMs}ms`)
🧰 Tools
🪛 ESLint

[error] 14-14: Unexpected console statement.

(no-console)

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

In `@src/events/WebhookEvent.ts` at line 14, Replace the direct console.log call
in WebhookEvent (the line using console.log(`Sending webhook event to
${webhookUrl} with timeout of ${timeoutMs}ms`)) with the injected logger by
calling logger.info with the same message; update any imports or class
constructor if needed to ensure the logger instance used by the
WebhookEvent.send/sendEvent (or whichever method contains that console.log) is
the injected logger so linting and structured logging are used consistently.

// 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()
Expand Down