Skip to content

fix(frontend): use per-instance webhook secret in copy-URL field#293

Merged
mescon merged 1 commit into
mainfrom
fix/webhook-url-uses-per-instance-secret
Jun 3, 2026
Merged

fix(frontend): use per-instance webhook secret in copy-URL field#293
mescon merged 1 commit into
mainfrom
fix/webhook-url-uses-per-instance-secret

Conversation

@mescon
Copy link
Copy Markdown
Owner

@mescon mescon commented Jun 3, 2026

Problem

The webhook URL shown in each Arr-instance row was hardcoded to the master API key:

/api/webhook/<id>?apikey={apiKeyData?.api_key}

When the instance has a per-instance `webhook_secret` (default for any instance created after the per-instance-secret migration), the backend at `handlers_webhook.go:86-97` rejects requests authenticated with the master key:

401 Unauthorized {"error":"Invalid webhook secret"}

#286 reports exactly this: user copied the URL verbatim from the UI into Sonarr's webhook config, Sonarr's connection test failed with the 401.

Fix

  • `ArrServersSection.tsx`: per-row URL uses `arr.webhook_secret` if present, falls back to `apiKeyData?.api_key` for legacy rows.
  • `ArrInstance` type gains the optional `webhook_secret` field (the API already returns it).
  • `Config.tsx` master-key card: rename "Webhook API Key" → "Master API Key", revise copy to call itself a fallback for legacy instances. The amber banner is repurposed as the legacy URL format with a "prefer the per-instance URL" hint.

Closes #286.

Test plan

  • `npm run build` clean
  • `npm run typecheck` clean
  • `go build ./...` clean
  • After deploy: verify on production that POSTing to /api/webhook/?apikey=<webhook_secret> returns 2xx, and POSTing with the master key returns 401 (because the instance has a per-instance secret)

Summary by CodeRabbit

  • New Features

    • Added support for per-instance webhook secrets as an alternative to the master API key.
    • Webhook URLs now automatically use per-instance secrets when available, with automatic fallback to the master API key.
  • Documentation

    • Improved clarity in Security settings with updated API key labeling and guidance.

The webhook URL shown in each Arr-instance row was hardcoded to the
master API key:

  /api/webhook/<id>?apikey=${apiKeyData?.api_key}

When the instance has a per-instance webhook_secret (the default for
any instance created after the per-instance-secret migration), the
backend rejects requests authenticated with the master API key:

  401 Unauthorized {"error":"Invalid webhook secret"}

The user who reported #286 copied the URL verbatim from the Healarr
UI into Sonarr's webhook config and got exactly that rejection.

Fix the per-row URL to prefer arr.webhook_secret over the master
api_key, and revise the Config-page master-key card to call itself
a 'Master API Key' (fallback only) so users don't try to use it
for webhooks on instances that have moved to per-instance secrets.

Closes #286
@mescon mescon merged commit dd0e0eb into main Jun 3, 2026
0 of 2 checks passed
@mescon mescon deleted the fix/webhook-url-uses-per-instance-secret branch June 3, 2026 21:45
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jun 3, 2026

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 23c14608-3750-43af-8806-ed4c39107cc1

📥 Commits

Reviewing files that changed from the base of the PR and between 03f6a31 and 2ba038e.

📒 Files selected for processing (3)
  • frontend/src/components/config/ArrServersSection.tsx
  • frontend/src/lib/api.ts
  • frontend/src/pages/Config.tsx

📝 Walkthrough

Walkthrough

The PR adds per-instance webhook secret support to Healarr. ArrInstance now includes an optional webhook_secret field, webhook URLs prefer this per-instance secret when present, and the Security section UI clarifies that the master API key serves as a legacy fallback for instances without per-instance secrets.

Changes

Per-Instance Webhook Secret Support

Layer / File(s) Summary
Per-instance webhook secret data and UI integration
frontend/src/lib/api.ts, frontend/src/components/config/ArrServersSection.tsx, frontend/src/pages/Config.tsx
ArrInstance includes optional webhook_secret field. Webhook URL generation in ArrServersSection prefers per-instance secrets over the master API key. Security section labels updated to describe "Master API Key" as a legacy fallback and emphasize per-instance webhook URLs as the preferred option.

Estimated code review effort

🎯 1 (Trivial) | ⏱️ ~4 minutes

Possibly related PRs

  • mescon/Healarr#189: Complements this PR's frontend per-instance webhook secret support with backend changes to introduce per-instance webhook_secret for webhook authentication.

Poem

🐰 A secret per server, no longer one key,
Webhooks now whisper with authenticity!
From master to instance, the preference flows clear,
Legacy fallbacks fade as new paths appear. 🔐

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/webhook-url-uses-per-instance-secret

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Jun 3, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

mescon added a commit that referenced this pull request Jun 4, 2026
… (#299)

The path-matching logic between *arr-reported paths and configured
scan paths required the post-prefix remainder to begin with a forward
slash. On Windows, Sonarr/Radarr report paths verbatim with UNC roots
and backslash separators, e.g.:

  \\alexpr4100\\media\\Movies\\High Strung (2016)\\film.mkv

With a scan path configured as \\alexpr4100\\media\\Movies, the
HasPrefix match succeeded but the remainder validation (which only
accepted '/') rejected the match. Every Windows-hosted setup got:

  Webhook path mapping failed: *arr reported path '...' but no
  matching scan path found

even with a correctly configured scan path.

Fix: accept either / or \\ as the directory-boundary separator after
a prefix match, and strip either as a trailing separator at load time.
Helpers are factored out (pathSeparators, hasSepPrefix,
trimTrailingSep) so the rule is named once and applied consistently
across Reload / ToArrPath / ToLocalPath.

Reported by alex882001 in #298. The earlier per-instance webhook
secret fix (#293, v1.3.6) was a prerequisite for this report — without
it the request would have been rejected at the auth gate before ever
reaching path mapping.

Closes #298

Co-authored-by: mescon <mescon@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Webhook Creation Issue

1 participant