From e97dd4251f9b9d06860fa1b73bcf14a72bacf56a Mon Sep 17 00:00:00 2001 From: Yudhi Armyndharis Date: Sun, 12 Jul 2026 08:17:29 +0700 Subject: [PATCH] chore(http-action): set 0.1.0 status to beta and add a secret sentinel test Promotes http-action 0.1.0 from development to beta ahead of its first tagged release. Adds a sentinel test asserting the configured auth token is placed in the outbound request header (auth path exercised) yet never appears in logs or the sent reply, and regenerates the catalog so the status change propagates to plugins.json and the README detail blocks. --- README.md | 2 +- http-action/README.md | 2 +- http-action/index.test.ts | 23 +++++++++++++++++++++++ http-action/manifest.json | 2 +- plugins.json | 2 +- 5 files changed, 27 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index bd53095..3032922 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ This repository provides: | [`faq-bot`](./faq-bot) | Auto-replies to inbound WhatsApp messages from configurable FAQ keyword/regex rules. | 0.1.6 | stable | | [`group-translate`](./group-translate) | Auto-translates group messages between participants' languages via a LibreTranslate backend. Configure in-chat with /tr commands. Admin-gated; disabled until enabled. | 1.0.5 | stable | | [`gsheets-logger`](./gsheets-logger) | Logs WhatsApp message events to a Google Sheet via a service account. | 0.2.3 | stable | -| [`http-action`](./http-action) | Triggers safe REST API requests from WhatsApp commands and renders JSON responses back to chat. | 0.1.0 | development | +| [`http-action`](./http-action) | Triggers safe REST API requests from WhatsApp commands and renders JSON responses back to chat. | 0.1.0 | beta | | [`supabase-otp-hook`](./supabase-otp-hook) | Deliver Supabase Auth phone OTPs over WhatsApp. | 0.1.0 | beta | | [`typebot-connector`](./typebot-connector) | Runs a Typebot flow as the brain of a WhatsApp bot: inbound messages drive a Typebot chat session via the live Chat API, and the bot's replies โ€” text, media, and numbered-choice inputs โ€” are sent back to WhatsApp. Auto-starts every chat, handles file-upload steps, and resets when the flow ends or after an idle timeout. Runs sandboxed in the plugin worker; no public URL or webhook required. | 0.1.0 | beta | | [`voice-transcription`](./voice-transcription) | Transcribes inbound WhatsApp voice notes to text via an OpenAI-compatible speech-to-text backend (self-hosted Speaches/faster-whisper or hosted Groq/OpenAI) and delivers a `message.transcription` event to your webhook โ€” so bots and AI can read and reply to audio. Off the message-delivery path; disabled until enabled. | 1.0.1 | beta | diff --git a/http-action/README.md b/http-action/README.md index bf68d7c..2c38fb7 100644 --- a/http-action/README.md +++ b/http-action/README.md @@ -15,7 +15,7 @@ | **Identifier** | `http-action` | | **Version** | 0.1.0 | | **Released** | 2026-07-11 | -| **Status** | development | +| **Status** | beta | | **Author** | Yudhi Armyndharis | | **License** | MIT | | **Type** | `extension` | diff --git a/http-action/index.test.ts b/http-action/index.test.ts index 49b0a14..89eb9f9 100644 --- a/http-action/index.test.ts +++ b/http-action/index.test.ts @@ -192,3 +192,26 @@ test('send failure leaves the message un-marked: a redelivery after the cooldown assert.equal(sendCalls.length, 1); // retried send succeeded assert.equal(await hasSeen(storage, 's1', 'm1'), true); // marked only after the successful send }); + +// ---- sentinel (DoD ยง7): the auth token is used in the header but never reaches logs or the reply ---- +test('sentinel: the auth token is sent in the header yet never appears in logs or the reply', async () => { + const SECRET = 'SENTINEL-do-not-leak-9f3k2'; + const logged: unknown[] = []; + const sendCalls: { env: unknown }[] = []; + let capturedHeaders: Record | undefined; + const cfg = cfgWith({ authType: 'bearer', authToken: SECRET }); + const d: HandleDeps = { + cfg, storage: fakeStore(), cooldown: new Map(), now: () => 1000, + fetch: async (_u, init) => { capturedHeaders = init?.headers; throw new Error('upstream failure'); }, + conversations: { send: async (env: unknown) => { sendCalls.push({ env }); } }, + logger: { + log: (m: string) => logged.push(m), + warn: (m: string, e?: unknown) => logged.push([m, e]), + error: (m: string, e?: unknown) => logged.push([m, e]), + }, + }; + await handleMessage(d, 's1', msg('cek X')); + assert.ok(capturedHeaders?.Authorization?.includes(SECRET), 'sanity: secret is in the request header (used, not absent)'); + const haystack = `${JSON.stringify(logged)}${JSON.stringify(sendCalls)}`; + assert.ok(!haystack.includes(SECRET), 'auth token must never appear in logs or the reply'); +}); diff --git a/http-action/manifest.json b/http-action/manifest.json index 8c2bd3f..eaa8f5c 100644 --- a/http-action/manifest.json +++ b/http-action/manifest.json @@ -10,7 +10,7 @@ "homepage": "https://github.com/rmyndharis/OpenWA-plugins/tree/main/http-action", "repository": "https://github.com/rmyndharis/OpenWA-plugins", "keywords": ["api", "rest", "automation", "connector", "whatsapp", "openwa"], - "status": "development", + "status": "beta", "minOpenWAVersion": "0.8.7", "sdkVersion": "1", "provides": ["api-automation", "rest-connector", "dynamic-reply"], diff --git a/plugins.json b/plugins.json index a1e20d9..e34450e 100644 --- a/plugins.json +++ b/plugins.json @@ -1007,7 +1007,7 @@ "name": "HTTP Action Bot", "version": "0.1.0", "type": "extension", - "status": "development", + "status": "beta", "description": "Triggers safe REST API requests from WhatsApp commands and renders JSON responses back to chat.", "author": "Yudhi Armyndharis ", "license": "MIT",