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>
65 lines
1.8 KiB
Go
65 lines
1.8 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
)
|
|
|
|
// httpBase is the prefix the host mounts the plugin HTTP handler at; the wasm
|
|
// host forwards full paths, so every route registers under it.
|
|
const httpBase = "/api/plugins/calcomblock"
|
|
|
|
// publishedConfigsSource is the slice of content.Content the resolver needs
|
|
// (satisfied by deps.Content).
|
|
type publishedConfigsSource interface {
|
|
PublishedBlockConfigs(ctx context.Context, blockKey string) ([]map[string]any, error)
|
|
}
|
|
|
|
// publishedBlockResolver answers CalcomBookingRequiresCaptcha from published
|
|
// block content served by the host (content.published_block_configs) — the
|
|
// server-authoritative source, never the POST body/blockId. A config with an
|
|
// empty username applies to any posted username (it falls back to the
|
|
// plugin's default account), erring toward requiring captcha.
|
|
type publishedBlockResolver struct {
|
|
source publishedConfigsSource
|
|
}
|
|
|
|
func (r publishedBlockResolver) CalcomBookingRequiresCaptcha(ctx context.Context, username, eventTypeSlug string) (bool, error) {
|
|
configs, err := r.source.PublishedBlockConfigs(ctx, "calcom:booking")
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
for _, cfg := range configs {
|
|
if !configBool(cfg["captchaEnabled"]) {
|
|
continue
|
|
}
|
|
if !configFieldMatches(cfg["eventTypeSlug"], eventTypeSlug, false) {
|
|
continue
|
|
}
|
|
if configFieldMatches(cfg["username"], username, true) {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func configBool(v any) bool {
|
|
switch b := v.(type) {
|
|
case bool:
|
|
return b
|
|
case string:
|
|
return strings.EqualFold(strings.TrimSpace(b), "true")
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func configFieldMatches(cfgValue any, posted string, emptyMatchesAny bool) bool {
|
|
s, _ := cfgValue.(string)
|
|
s = strings.TrimSpace(s)
|
|
if s == "" {
|
|
return emptyMatchesAny
|
|
}
|
|
return strings.EqualFold(s, strings.TrimSpace(posted))
|
|
}
|