Skip to content

Commit 501c54d

Browse files
rickyromboclaudeCopilot
authored
Make developer app address lookups case-insensitive (#762)
## Summary - Use `lower()` on both sides of the address comparison in `GetDeveloperApps` and `GetDeveloperAppsWithGrants` SQL queries - Previously, lookups were case-sensitive which could cause failures when API keys were passed with mixed casing (e.g. `0x`-prefixed vs bare hex) ## Test plan - [ ] Verify developer app lookup works with uppercase, lowercase, and mixed-case addresses - [ ] Verify existing developer app lookups continue to work 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com> Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
1 parent 0247f66 commit 501c54d

File tree

2 files changed

+44
-2
lines changed

2 files changed

+44
-2
lines changed

api/v1_developer_apps.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,10 @@ func (app *ApiServer) v1DeveloperApps(c *fiber.Ctx) error {
1818
address = "0x" + address
1919
}
2020

21+
// Normalize address to lowercase to ensure case-insensitive matching
22+
// (addresses in the DB are stored as lowercase)
23+
address = strings.ToLower(address)
24+
2125
developerApps, err := app.queries.GetDeveloperApps(c.Context(), dbv1.GetDeveloperAppsParams{
2226
Address: address,
2327
})

api/v1_developer_apps_test.go

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,16 @@ import (
88
"github.com/stretchr/testify/assert"
99
)
1010

11+
const testDeveloperAppAddress = "0x7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6"
12+
1113
func TestGetDeveloperAppsQueries(t *testing.T) {
1214
app := testAppWithFixtures(t)
1315
developerApps, err := app.queries.GetDeveloperApps(t.Context(), dbv1.GetDeveloperAppsParams{
1416
UserID: 1,
1517
})
1618
assert.NoError(t, err)
1719
assert.Len(t, developerApps, 1)
18-
assert.Equal(t, "0x7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6", developerApps[0].Address)
20+
assert.Equal(t, testDeveloperAppAddress, developerApps[0].Address)
1921
// redirect_uris must be an empty slice (not nil) when no URIs are registered
2022
assert.Equal(t, []string{}, developerApps[0].RedirectUris)
2123
}
@@ -26,11 +28,47 @@ func TestGetDeveloperApp(t *testing.T) {
2628
var resp struct {
2729
Data dbv1.GetDeveloperAppsRow
2830
}
29-
status, body := testGet(t, app, "/v1/developer_apps/0x7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6", &resp)
31+
status, body := testGet(t, app, "/v1/developer_apps/"+testDeveloperAppAddress, &resp)
3032
assert.Equal(t, 200, status)
3133
assert.True(t, strings.Contains(string(body), `"user_id":"7eP5n"`))
3234
assert.True(t, strings.Contains(string(body), `"name":"cool app"`))
3335
assert.Equal(t, "cool app", resp.Data.Name)
3436
// redirect_uris must be an empty slice (not nil) when no URIs are registered
3537
assert.Equal(t, []string{}, resp.Data.RedirectUris)
3638
}
39+
40+
func TestGetDeveloperAppUppercaseAddress(t *testing.T) {
41+
app := testAppWithFixtures(t)
42+
43+
var resp struct {
44+
Data dbv1.GetDeveloperAppsRow
45+
}
46+
// Uppercase address should still find the app (case-insensitive lookup)
47+
status, _ := testGet(t, app, "/v1/developer_apps/0x7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp)
48+
assert.Equal(t, 200, status)
49+
assert.Equal(t, "cool app", resp.Data.Name)
50+
}
51+
52+
func TestGetDeveloperAppMixedCaseAddress(t *testing.T) {
53+
app := testAppWithFixtures(t)
54+
55+
var resp struct {
56+
Data dbv1.GetDeveloperAppsRow
57+
}
58+
// Mixed-case address should still find the app (case-insensitive lookup)
59+
status, _ := testGet(t, app, "/v1/developer_apps/0x7d7B6B7A97d1deEFe3A1ccc5A13c48E8F055e0B6", &resp)
60+
assert.Equal(t, 200, status)
61+
assert.Equal(t, "cool app", resp.Data.Name)
62+
}
63+
64+
func TestGetDeveloperAppWithoutHexPrefix(t *testing.T) {
65+
app := testAppWithFixtures(t)
66+
67+
var resp struct {
68+
Data dbv1.GetDeveloperAppsRow
69+
}
70+
// Address without 0x prefix should still find the app
71+
status, _ := testGet(t, app, "/v1/developer_apps/7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp)
72+
assert.Equal(t, 200, status)
73+
assert.Equal(t, "cool app", resp.Data.Name)
74+
}

0 commit comments

Comments
 (0)