Skip to content

Commit 6a39314

Browse files
committed
fix: store jsonb
1 parent 5cb16d5 commit 6a39314

File tree

2 files changed

+37
-22
lines changed

2 files changed

+37
-22
lines changed

internal/models/custom_oauth_provider.go

Lines changed: 33 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,11 @@ import (
44
"database/sql"
55
"database/sql/driver"
66
"encoding/json"
7+
"fmt"
8+
"strings"
79
"time"
810

911
"github.com/gofrs/uuid"
10-
"github.com/lib/pq"
1112
"github.com/pkg/errors"
1213
"github.com/supabase/auth/internal/conf"
1314
"github.com/supabase/auth/internal/crypto"
@@ -156,7 +157,7 @@ func (p *CustomOAuthProvider) GetDiscoveryURL() string {
156157
return *p.Issuer + "/.well-known/openid-configuration"
157158
}
158159

159-
// StringSlice handles PostgreSQL text[] type
160+
// StringSlice handles JSON-encoded string arrays stored as jsonb
160161
type StringSlice []string
161162

162163
func (s *StringSlice) Scan(src interface{}) error {
@@ -165,26 +166,42 @@ func (s *StringSlice) Scan(src interface{}) error {
165166
return nil
166167
}
167168

168-
// Create a temporary []string slice and scan into it
169+
var b []byte
170+
switch v := src.(type) {
171+
case []byte:
172+
b = v
173+
case string:
174+
b = []byte(v)
175+
default:
176+
return fmt.Errorf("cannot scan %T into StringSlice", src)
177+
}
178+
179+
// Handle empty/null JSON values
180+
b = []byte(strings.TrimSpace(string(b)))
181+
if len(b) == 0 || string(b) == "null" || string(b) == "[]" {
182+
*s = []string{}
183+
return nil
184+
}
185+
169186
var tmp []string
170-
if err := pq.Array(&tmp).Scan(src); err != nil {
171-
return errors.Wrap(err, "error scanning string slice")
187+
if err := json.Unmarshal(b, &tmp); err != nil {
188+
return errors.Wrap(err, "error unmarshaling StringSlice")
172189
}
173190

174-
// Convert to StringSlice
175191
*s = StringSlice(tmp)
176192
return nil
177193
}
178194

179195
func (s StringSlice) Value() (driver.Value, error) {
180196
if s == nil || len(s) == 0 {
181-
return "{}", nil
197+
return []byte("[]"), nil
182198
}
183199

184-
// Convert StringSlice to []string and use pq.Array
185-
// This will handle escaping and formatting correctly
186-
tmp := []string(s)
187-
return pq.Array(tmp).Value()
200+
b, err := json.Marshal([]string(s))
201+
if err != nil {
202+
return nil, errors.Wrap(err, "error marshaling StringSlice")
203+
}
204+
return b, nil
188205
}
189206

190207
// OAuthAttributeMapping defines how to map provider attributes to user fields
@@ -214,15 +231,15 @@ func (m *OAuthAttributeMapping) Scan(src interface{}) error {
214231

215232
func (m OAuthAttributeMapping) Value() (driver.Value, error) {
216233
if m == nil {
217-
return "{}", nil
234+
return []byte("{}"), nil
218235
}
219236

220237
b, err := json.Marshal(m)
221238
if err != nil {
222239
return nil, errors.Wrap(err, "error marshaling attribute mapping")
223240
}
224241

225-
return string(b), nil
242+
return b, nil
226243
}
227244

228245
// OAuthAuthorizationParams holds additional parameters for authorization requests
@@ -252,15 +269,15 @@ func (p *OAuthAuthorizationParams) Scan(src interface{}) error {
252269

253270
func (p OAuthAuthorizationParams) Value() (driver.Value, error) {
254271
if p == nil {
255-
return "{}", nil
272+
return []byte("{}"), nil
256273
}
257274

258275
b, err := json.Marshal(p)
259276
if err != nil {
260277
return nil, errors.Wrap(err, "error marshaling authorization params")
261278
}
262279

263-
return string(b), nil
280+
return b, nil
264281
}
265282

266283
// OIDCDiscovery represents cached OIDC discovery document
@@ -307,7 +324,7 @@ func (d *OIDCDiscovery) Value() (driver.Value, error) {
307324
return nil, errors.Wrap(err, "error marshaling OIDC discovery")
308325
}
309326

310-
return string(b), nil
327+
return b, nil
311328
}
312329

313330
// CRUD operations for CustomOAuthProvider

migrations/20260128120000_add_custom_oauth_providers.up.sql

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ create table if not exists {{ index .Options "Namespace" }}.custom_oauth_provide
1313
name text not null,
1414
client_id text not null,
1515
client_secret text not null, -- Encrypted at application level
16-
acceptable_client_ids text[] not null default array[]::text[], -- Additional client IDs for multi-platform apps
17-
scopes text[] not null default array[]::text[],
16+
-- Store JSON-encoded string slices in jsonb columns
17+
acceptable_client_ids jsonb not null default '[]'::jsonb, -- Additional client IDs for multi-platform apps
18+
scopes jsonb not null default '[]'::jsonb,
1819
pkce_enabled boolean not null default true,
1920
attribute_mapping jsonb not null default '{}',
2021
authorization_params jsonb not null default '{}',
@@ -93,10 +94,7 @@ create table if not exists {{ index .Options "Namespace" }}.custom_oauth_provide
9394
),
9495
constraint custom_oauth_providers_client_id_length check (
9596
char_length(client_id) >= 1 and char_length(client_id) <= 512
96-
),
97-
constraint custom_oauth_providers_client_secret_length check (
98-
char_length(client_secret) >= 1 and char_length(client_secret) <= 1024
99-
),
97+
)
10098
);
10199

102100
/* auth_migration: 20260128120000 */

0 commit comments

Comments
 (0)