Skip to content

Commit 610cc5c

Browse files
committed
fix(client): add omitempty to optional URI fields in JSON serialization
Optional fields (policy_uri, tos_uri, client_uri, logo_uri, contacts) were serialized as empty strings or null when not set. This breaks strict JSON validators like Zod that expect these fields to either be present with valid values or omitted entirely. RFC 7591 specifies these fields as optional, so omitting them when empty is the correct behavior for DCR responses.
1 parent 028908f commit 610cc5c

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

client/client.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ type Client struct {
110110
// PolicyURI is a URL string that points to a human-readable privacy policy document
111111
// that describes how the deployment organization collects, uses,
112112
// retains, and discloses personal data.
113-
PolicyURI string `json:"policy_uri" db:"policy_uri"`
113+
PolicyURI string `json:"policy_uri,omitempty" db:"policy_uri"`
114114

115115
// OAuth 2.0 Client Allowed CORS Origins
116116
//
@@ -126,27 +126,27 @@ type Client struct {
126126
// document for the client that describes a contractual relationship
127127
// between the end-user and the client that the end-user accepts when
128128
// authorizing the client.
129-
TermsOfServiceURI string `json:"tos_uri" db:"tos_uri"`
129+
TermsOfServiceURI string `json:"tos_uri,omitempty" db:"tos_uri"`
130130

131131
// OAuth 2.0 Client URI
132132
//
133133
// ClientURI is a URL string of a web page providing information about the client.
134134
// If present, the server SHOULD display this URL to the end-user in
135135
// a clickable fashion.
136-
ClientURI string `json:"client_uri" db:"client_uri"`
136+
ClientURI string `json:"client_uri,omitempty" db:"client_uri"`
137137

138138
// OAuth 2.0 Client Logo URI
139139
//
140140
// A URL string referencing the client's logo.
141-
LogoURI string `json:"logo_uri" db:"logo_uri"`
141+
LogoURI string `json:"logo_uri,omitempty" db:"logo_uri"`
142142

143143
// OAuth 2.0 Client Contact
144144
//
145145
// An array of strings representing ways to contact people responsible
146146
// for this client, typically email addresses.
147147
//
148148
// Example: help@example.org
149-
Contacts sqlxx.StringSliceJSONFormat `json:"contacts" db:"contacts"`
149+
Contacts sqlxx.StringSliceJSONFormat `json:"contacts,omitempty" db:"contacts"`
150150

151151
// OAuth 2.0 Client Secret Expires At
152152
//

client/client_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@
44
package client
55

66
import (
7+
"encoding/json"
78
"testing"
89

910
"github.com/stretchr/testify/assert"
11+
"github.com/stretchr/testify/require"
1012

1113
"github.com/ory/hydra/v2/fosite"
1214
)
@@ -31,3 +33,34 @@ func TestClient(t *testing.T) {
3133
assert.Len(t, c.GetScopes(), 2)
3234
assert.EqualValues(t, c.RedirectURIs, c.GetRedirectURIs())
3335
}
36+
37+
func TestClientJSONOmitsEmptyOptionalURIFields(t *testing.T) {
38+
c := &Client{
39+
ID: "test-client",
40+
RedirectURIs: []string{"http://localhost/callback"},
41+
}
42+
43+
data, err := json.Marshal(c)
44+
require.NoError(t, err)
45+
46+
var result map[string]interface{}
47+
err = json.Unmarshal(data, &result)
48+
require.NoError(t, err)
49+
50+
// These optional URI fields should be omitted when empty, not serialized as ""
51+
_, hasLogoURI := result["logo_uri"]
52+
assert.False(t, hasLogoURI, "logo_uri should be omitted when empty")
53+
54+
_, hasTosURI := result["tos_uri"]
55+
assert.False(t, hasTosURI, "tos_uri should be omitted when empty")
56+
57+
_, hasPolicyURI := result["policy_uri"]
58+
assert.False(t, hasPolicyURI, "policy_uri should be omitted when empty")
59+
60+
_, hasClientURI := result["client_uri"]
61+
assert.False(t, hasClientURI, "client_uri should be omitted when empty")
62+
63+
// contacts should be omitted when nil, not serialized as null
64+
_, hasContacts := result["contacts"]
65+
assert.False(t, hasContacts, "contacts should be omitted when nil")
66+
}

0 commit comments

Comments
 (0)