Files
GeorgeandClaude Sonnet 5 5e0df73477 Initial commit: sap-webhook-api
API NestJS que recibe el Webhook Messenger de SAP Business One
(CloudEvents), valida HMAC opcional y guarda cada notificacion
local (data/events/) e inserta en Postgres (webhook_events).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-16 07:41:25 -05:00

3.9 KiB

Cómo ejecutar la API (con y sin HMAC)

Guía rápida para levantar sap-webhook-api en los dos modos soportados: sin autenticación (AuthenticationType: None, el modo actual de la suscripción real en SAP) y con firma HMAC.

0. Una sola vez: preparar el entorno

cd sap-webhook-api
npm install
cp .env.example .env   # si todavía no existe .env

Revisá que .env tenga los datos correctos de tu Service Layer (SERVICE_LAYER_URL, COMPANY_DB, SL_USER, SL_PASS, WEBHOOK_ID). El certificado HTTPS (certs/key.pem / certs/cert.pem) ya debería existir — si no, ver PASOS-REALIZADOS.md, sección 9.

Importante: el modo con el que arranca la API (.env → HMAC_SECRET_KEY) tiene que coincidir con el AuthenticationType configurado en la suscripción real de SAP. Si no coinciden, SAP manda notificaciones que la API rechaza (o al revés, la API acepta sin validar nada aunque SAP crea que está firmando). Los scripts de la sección 2 se encargan de mantenerlos sincronizados.

1. Modo sin autenticación (AuthenticationType: None)

Es el modo por defecto — no requiere ningún paso extra.

# confirmá que HMAC_SECRET_KEY esté vacío en .env
npm run start

La API queda escuchando en https://<tu-ip>:3000/webhooks/sap, acepta cualquier notificación sin validar firma. Prueba local:

curl -sk -i -X POST https://localhost:3000/webhooks/sap \
  -H "Content-Type: application/json" \
  -d '[{"id":"test-1","type":"sap.b1.Orders.Created.v1","subject":"1","data":{"DocEntry":"1"}}]'
# -> 200 OK

2. Modo con HMAC (AuthenticationType: HMAC)

2.1 Activar

npm run auth:hmac:on

Esto:

  1. Genera un HMAC_SECRET_KEY (si .env no tenía uno) y lo guarda en .env.
  2. Hace Login en el Service Layer, lee la configuración actual de la suscripción (WEBHOOK_ID de .env), la pausa, la elimina y la vuelve a crear con AuthenticationType: "HMAC" — el Service Layer no permite cambiar AuthenticationType con PATCH sobre una suscripción existente, así que este es el único camino soportado (se conserva WebhookURL, Handshake y EventCollection originales). AuthenticationCred no es el secreto pelado: va como un string con JSON embebido, {"Key": "<secreto>", "Algorithm": "hmacsha256"}.

Después, reiniciá la API para que tome el HMAC_SECRET_KEY nuevo:

npm run start

A partir de este momento, todo POST /webhooks/sap sin la firma correcta en el header X-B1-Webhook-Signature (HMAC-SHA256 del body, en base64) devuelve 401 Unauthorized.

2.2 Probar manualmente (simulando lo que hace SAP)

SECRET=$(grep '^HMAC_SECRET_KEY=' .env | cut -d= -f2)
BODY='[{"id":"test-2","type":"sap.b1.Orders.Created.v1","subject":"2","data":{"DocEntry":"2"}}]'
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -binary | openssl base64)

curl -sk -i -X POST https://localhost:3000/webhooks/sap \
  -H "Content-Type: application/json" \
  -H "X-B1-Webhook-Signature: $SIG" \
  -d "$BODY"
# -> 200 OK

# sin firma o con una firma incorrecta -> 401
curl -sk -i -X POST https://localhost:3000/webhooks/sap \
  -H "Content-Type: application/json" -d "$BODY"

2.3 Desactivar (volver a None)

npm run auth:hmac:off
npm run start   # reiniciar para que la API deje de exigir la firma

Esto revierte la suscripción en SAP a AuthenticationType: "None" y vacía HMAC_SECRET_KEY en .env, en un solo paso.

Referencia rápida

Acción Comando
Instalar dependencias npm install
Levantar la API npm run start
Activar HMAC (API + SAP) npm run auth:hmac:on
Desactivar HMAC (API + SAP) npm run auth:hmac:off
Ver estado actual de la suscripción curl -sk -b cookies.txt "$SERVICE_LAYER_URL/EventSubscriptions('$WEBHOOK_ID')" (después de un Login)

Detalle de la implementación (cómo se valida la firma, por qué se usa el body crudo, etc.) en CLAUDE.md.