Context does not cross the wasm ABI, so requireAdmin's
auth.GetUserFromContext only sees claims if the guest rebuilds them from
the host-stamped X-Bn-Verified-* headers. 2.0.3 never mounted
auth.TrustedHeaderMiddleware, so every admin endpoint (settings save,
event-types, test, rotate) returned 401 for real admins — the settings
panel could not store the Cal.com API key. Mount the middleware on the
router and pin the contract with a header-driven test (viewer headers
must reach requireAdmin and 403, never 401): the existing admin tests
injected claims straight into context, which is exactly the path wasm
does not have.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two wasm-era regressions fixed:
Routes: the wasm host forwards the FULL request path with no prefix
strip, but every route was registered relative — the plugin's entire
HTTP surface (slots/book/cancel/date-grid/admin) 404'd at runtime on
every instance since 2.0.0. All routes now register under
/api/plugins/calcomblock (testplugin's httpBase convention), pinned by
a route-matching test.
Captcha requirement: blockConfig was hardcoded nil (no capability
exposed published block content), so bookingRequiresCaptcha always
reported false — the widget never rendered and the gate never ran.
publishedBlockResolver now answers it via pluginsdk v0.2.4's
content.published_block_configs: any currently-published calcom:booking
block matching the posted username+eventTypeSlug with
captchaEnabled=true demands the host-stamped X-Bn-Verified-Captcha
header; an empty config username applies to any posted username.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>