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>
91 lines
3.5 KiB
Bash
Executable File
91 lines
3.5 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Activa AuthenticationType: HMAC en la suscripción de SAP, sincronizado
|
|
# con HMAC_SECRET_KEY de .env (lo genera si todavía no existe).
|
|
#
|
|
# El Service Layer no permite cambiar AuthenticationType con PATCH sobre
|
|
# una suscripción existente -> hay que Pause + Delete + volver a crearla
|
|
# (POST), reusando su WebhookURL/Handshake/EventCollection actuales.
|
|
set -euo pipefail
|
|
cd "$(dirname "$0")/.."
|
|
|
|
ENV_FILE=".env"
|
|
[ -f "$ENV_FILE" ] || { echo "No existe $ENV_FILE (copiá .env.example primero)"; exit 1; }
|
|
set -a
|
|
source "$ENV_FILE"
|
|
set +a
|
|
|
|
if [ -z "${HMAC_SECRET_KEY:-}" ]; then
|
|
HMAC_SECRET_KEY="$(openssl rand -base64 32)"
|
|
if grep -q '^HMAC_SECRET_KEY=' "$ENV_FILE"; then
|
|
sed -i.bak "s|^HMAC_SECRET_KEY=.*|HMAC_SECRET_KEY=$HMAC_SECRET_KEY|" "$ENV_FILE"
|
|
rm -f "$ENV_FILE.bak"
|
|
else
|
|
echo "HMAC_SECRET_KEY=$HMAC_SECRET_KEY" >> "$ENV_FILE"
|
|
fi
|
|
echo "Se generó un HMAC_SECRET_KEY nuevo y se guardó en $ENV_FILE"
|
|
fi
|
|
|
|
: "${SERVICE_LAYER_URL:?Falta SERVICE_LAYER_URL en .env}"
|
|
: "${COMPANY_DB:?Falta COMPANY_DB en .env}"
|
|
: "${SL_USER:?Falta SL_USER en .env}"
|
|
: "${SL_PASS:?Falta SL_PASS en .env}"
|
|
: "${WEBHOOK_ID:?Falta WEBHOOK_ID en .env}"
|
|
|
|
COOKIE_JAR="$(mktemp)"
|
|
trap 'rm -f "$COOKIE_JAR"' EXIT
|
|
|
|
echo "Login en Service Layer ($SERVICE_LAYER_URL, compañía $COMPANY_DB)..."
|
|
curl -sk -c "$COOKIE_JAR" -o /dev/null -w " -> HTTP %{http_code}\n" \
|
|
-X POST "$SERVICE_LAYER_URL/Login" \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"CompanyDB\":\"$COMPANY_DB\",\"UserName\":\"$SL_USER\",\"Password\":\"$SL_PASS\"}"
|
|
|
|
echo "Leyendo configuración actual de '$WEBHOOK_ID'..."
|
|
CURRENT=$(curl -sk -b "$COOKIE_JAR" "$SERVICE_LAYER_URL/EventSubscriptions('$WEBHOOK_ID')")
|
|
|
|
NEW_BODY=$(echo "$CURRENT" | HMAC_KEY="$HMAC_SECRET_KEY" python3 -c "
|
|
import json, os, sys
|
|
current = json.load(sys.stdin)
|
|
cred = json.dumps({'Key': os.environ['HMAC_KEY'], 'Algorithm': 'hmacsha256'})
|
|
body = {
|
|
'WebhookID': current['WebhookID'],
|
|
'WebhookURL': current['WebhookURL'],
|
|
'AuthenticationType': 'HMAC',
|
|
'AuthenticationCred': cred,
|
|
'Handshake': current.get('Handshake', 'tNO'),
|
|
'VerifyCertificate': current.get('VerifyCertificate', 'tNO'),
|
|
'EventCollection': [
|
|
{'BusinessObject': e['BusinessObject'], 'TransactionType': e['TransactionType']}
|
|
for e in current['EventCollection']
|
|
],
|
|
}
|
|
print(json.dumps(body))
|
|
")
|
|
|
|
echo "Pausando suscripción '$WEBHOOK_ID'..."
|
|
curl -sk -b "$COOKIE_JAR" -o /dev/null -w " -> HTTP %{http_code}\n" \
|
|
-X POST "$SERVICE_LAYER_URL/EventSubscriptions('$WEBHOOK_ID')/Pause"
|
|
|
|
echo "Eliminando suscripción '$WEBHOOK_ID'..."
|
|
curl -sk -b "$COOKIE_JAR" -o /dev/null -w " -> HTTP %{http_code}\n" \
|
|
-X DELETE "$SERVICE_LAYER_URL/EventSubscriptions('$WEBHOOK_ID')"
|
|
|
|
echo "Recreando '$WEBHOOK_ID' con AuthenticationType: HMAC..."
|
|
curl -sk -b "$COOKIE_JAR" -o /dev/null -w " -> HTTP %{http_code}\n" \
|
|
-X POST "$SERVICE_LAYER_URL/EventSubscriptions" \
|
|
-H "Content-Type: application/json" \
|
|
-d "$NEW_BODY"
|
|
|
|
# El POST de creación ignora el VerifyCertificate que mandamos y siempre
|
|
# arranca en tYES -> hace falta un PATCH aparte para volver a ponerlo en
|
|
# tNO (si no, SAP intenta validar nuestro cert autofirmado y falla con
|
|
# "SSL Certificate Untrusted", dejando la suscripción Inactive).
|
|
echo "Ajustando VerifyCertificate: tNO..."
|
|
curl -sk -b "$COOKIE_JAR" -o /dev/null -w " -> HTTP %{http_code}\n" \
|
|
-X PATCH "$SERVICE_LAYER_URL/EventSubscriptions('$WEBHOOK_ID')" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"VerifyCertificate": "tNO"}'
|
|
|
|
echo
|
|
echo "Listo. Reiniciá la API (npm run start) para que tome el HMAC_SECRET_KEY de .env."
|