Serve the OpenAccess descriptor at /.well-known/openaccess.json (#127)
Some checks failed
CI / build (push) Has been cancelled
deploy / deploy (push) Has been cancelled
test / test (push) Has been cancelled

Spec: https://logicsrc.com/openaccess

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

Claude-Session: https://claude.ai/code/session_01SWRffW4ifQPUrGXJtgYWMd
This commit is contained in:
Anthony Ettinger 2026-09-12 12:26:25 -07:00 • committed by GitHub
parent d2e4b56ae7
commit aad61eec17
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 101 additions and 0 deletions

View file

@ -2,6 +2,7 @@ package files
import (
"crypto/rand"
_ "embed"
"encoding/hex"
"errors"
"fmt"
@ -71,9 +72,40 @@ func (s *Service) WebHandler(cfg WebConfig) http.Handler {
mux.HandleFunc("/mkdir", h.handleMkdir)
mux.HandleFunc("/delete", h.handleDelete)
mux.HandleFunc("/healthz", func(w http.ResponseWriter, _ *http.Request) { _, _ = w.Write([]byte("ok")) })
mux.Handle(OpenAccessPath, OpenAccessHandler())
return mux
}
// OpenAccessPath is the well-known location of the OpenAccess descriptor
// (https://logicsrc.com/openaccess). Hubs such as openaccess.logicsrc.com fetch
// it to list the BBS and to link accounts with OAuth 2.1 + PKCE.
const OpenAccessPath = "/.well-known/openaccess.json"
// openAccessDescriptor is the static descriptor served verbatim. It names the
// public signing key (JWKS), the redirect URI and the hubs the BBS trusts.
//
//go:embed openaccess.json
var openAccessDescriptor []byte
// OpenAccessHandler serves the embedded OpenAccess descriptor as JSON with a
// short public cache. It needs no session: hubs fetch it anonymously.
func OpenAccessHandler() http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodGet && r.Method != http.MethodHead {
w.Header().Set("Allow", "GET, HEAD")
http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
return
}
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Cache-Control", "public, max-age=300")
w.Header().Set("Content-Length", strconv.Itoa(len(openAccessDescriptor)))
if r.Method == http.MethodHead {
return
}
_, _ = w.Write(openAccessDescriptor)
})
}
// --- session helpers --------------------------------------------------------
func (h *webSrv) lookup(r *http.Request) (string, bool) {