From b3f31f9037e2d540f07e15c040ad874f9639cb3a Mon Sep 17 00:00:00 2001 From: Matteo Vicini <1192305+cmatte@users.noreply.github.com> Date: Sun, 7 Jun 2026 11:28:39 +0000 Subject: [PATCH] =?UTF-8?q?fix(idp):=20apply=20RFC=207591=20=C2=A72=20defa?= =?UTF-8?q?ults=20to=20DCR=20registration?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The DCR handler stored req.GrantTypes, req.ResponseTypes, and req.TokenEndpointAuthMethod verbatim. When the caller omitted them, the persisted fosite client used empty values and the registration response returned `null` for the arrays and `""` for the auth method. Per RFC 7591 §2 the server should default these optional fields to `["authorization_code"]`, `["code"]`, and `"client_secret_basic"`. Strict clients (e.g. LM Studio's Zod schema) reject the non-compliant response with `expected array, received null`; lenient clients (Claude) tolerate it. Defaults are applied immediately after JSON binding, so both the stored client and the response inherit them in one place. Fixes #173 Co-Authored-By: Claude Opus 4.7 (1M context) --- pkg/idp/idp.go | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pkg/idp/idp.go b/pkg/idp/idp.go index e7088da..397a656 100644 --- a/pkg/idp/idp.go +++ b/pkg/idp/idp.go @@ -347,6 +347,20 @@ func (a *IDPRouter) handleRegister(c *gin.Context) { return } + // RFC 7591 §2: apply server-side defaults for omitted optional fields, so + // the persisted client and the registration response are spec-compliant. + // Strict clients (e.g. LM Studio's Zod schema) reject null/empty values + // here; any caller-supplied values are preserved verbatim. + if len(req.GrantTypes) == 0 { + req.GrantTypes = []string{"authorization_code"} + } + if len(req.ResponseTypes) == 0 { + req.ResponseTypes = []string{"code"} + } + if req.TokenEndpointAuthMethod == "" { + req.TokenEndpointAuthMethod = "client_secret_basic" + } + clientID, err := utils.GenerateClientID() if err != nil { a.logger.Error("Failed to generate client ID", zap.Error(err))