#8584: fix(nextcloud-talk): fix HMAC signing, allowlist matching, and graceful shutdown
channel: nextcloud-talk
stale
Cluster:
Session Management and Fixes
## Summary
- **Fix outbound HMAC signing**: Nextcloud's `BotController::getBotFromHeaders` verifies HMAC over `random + messageText` (or `random + reactionString`), not over `random + fullJsonBody`. Changed `generateNextcloudTalkSignature` calls to pass the extracted value, fixing 401 auth failures on all outbound sends.
- **Fix `users/` prefix mismatch**: Nextcloud webhooks send `actor.id` as `users/<username>` but allowlists typically contain bare usernames. Added `.replace(/^users\//, "")` to `normalizeAllowEntry` so `groupAllowFrom` and `allowFrom` matching works correctly.
- **Add `Accept: application/json` header**: Without it, Nextcloud returns XML error responses instead of JSON.
- **Add `stopAccount` lifecycle hook**: The webhook HTTP server was not stopped on SIGUSR1 reload, causing EADDRINUSE on restart. Added `accountStopFns` registry and `stopAccount` hook in `channel.ts`.
- **Make `stop()` properly awaitable**: Changed webhook server `stop()` from sync `server.close()` to `Promise<void>` with callback, ensuring clean shutdown.
- **Add signature verification debug logging**: Log details when inbound signature verification fails (was silently returning 401).
- **Add README**: Setup guide covering prerequisites, configuration, access control, per-room config, multi-account, and file layout.
## Files changed
All changes scoped to `extensions/nextcloud-talk/`:
| File | Change |
|------|--------|
| `src/send.ts` | HMAC signing fix, Accept header, 401 diagnostics |
| `src/policy.ts` | `users/` prefix stripping in `normalizeAllowEntry` |
| `src/policy.test.ts` | 2 new test cases for `users/` prefix handling |
| `src/channel.ts` | `stopAccount` hook with `accountStopFns` registry |
| `src/monitor.ts` | Awaitable `stop()`, signature failure logging |
| `README.md` | New setup and reference documentation |
## Test plan
- [x] `pnpm vitest run extensions/nextcloud-talk/src/policy.test.ts` — 5/5 pass
- [x] `pnpm build` — clean
- [x] `pnpm lint` — 0 warnings, 0 errors
- [x] End-to-end: gateway running, outbound message sent successfully to Nextcloud Talk room, webhook receiving inbound messages on port 8788
<!-- greptile_comment -->
<h2>Greptile Overview</h2>
<h3>Greptile Summary</h3>
This PR fixes Nextcloud Talk bot interoperability by aligning outbound HMAC signing with Nextcloud’s expected payload (signing `random + messageText` / `random + reactionText`), improving allowlist matching by normalizing `users/<id>` sender IDs, adding `Accept: application/json` to receive JSON error bodies, and making the webhook server shutdown path awaitable.
It also adds a per-account `stopAccount` lifecycle hook to stop webhook servers on reload, plus additional diagnostic logging for inbound signature verification failures and new README documentation for setup/config.
<h3>Confidence Score: 4/5</h3>
- This PR is largely safe to merge; the main risks are around lifecycle edge cases and noisy error logging.
- Changes are localized and align behavior with Nextcloud’s documented/observed signing rules, with tests added for allowlist normalization. Remaining concerns are edge-case lifecycle handling (overwriting stop fns without stopping prior instances) and abort-triggered shutdown errors being dropped, which could affect stability under reload/abort scenarios.
- extensions/nextcloud-talk/src/channel.ts, extensions/nextcloud-talk/src/monitor.ts
<!-- greptile_other_comments_section -->
<sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#11804: fix(webhook): return 503 from health endpoints when last processing...
by coygeek · 2026-02-08
79.0%
#20491: fix: address EADDRINUSE on Nextcloud Talk webhook restart
by MisterGuy420 · 2026-02-19
76.3%
#4878: fix: string/type handling and API fixes (#4537, #4380, #4373, #4547...
by lailoo · 2026-01-30
76.1%
#13881: fix: Address Greptile feedback - test isolation and channel resolution
by trevorgordon981 · 2026-02-11
75.3%
#11048: fix: address repository issues (env, author, CI comments, security ...
by cavula · 2026-02-07
75.0%
#20554: fix(googlechat): prevent infinite restart loop in startAccount
by Gitjay11 · 2026-02-19
74.9%
#20395: fix(googlechat): prevent infinite auto-restart and ambiguous-target...
by ggalmeida0 · 2026-02-18
74.8%
#15050: fix: transcript corruption resilience — strip aborted tool_use bloc...
by yashchitneni · 2026-02-12
74.4%
#21271: fix(commands): pass channel/capabilities/shell/os to runtime in com...
by evansantos · 2026-02-19
74.4%
#21463: fix(discord): prevent WebSocket death spiral + fix numeric channel ID…
by akropp · 2026-02-20
74.3%