From 92c0bb0baa10eff3ecaa85b0edf19b85adefa069 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Fri, 10 Apr 2026 11:50:01 -0700 Subject: [PATCH 1/3] Make developer app address lookups case-insensitive Use lower() on both sides of the address comparison in GetDeveloperApps and GetDeveloperAppsWithGrants queries. Co-Authored-By: Claude Opus 4.6 --- api/dbv1/get_developer_apps.sql.go | 4 ++-- api/dbv1/queries/get_developer_apps.sql | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/api/dbv1/get_developer_apps.sql.go b/api/dbv1/get_developer_apps.sql.go index 030fbf83..438840e6 100644 --- a/api/dbv1/get_developer_apps.sql.go +++ b/api/dbv1/get_developer_apps.sql.go @@ -24,7 +24,7 @@ SELECT FROM developer_apps da LEFT JOIN oauth_redirect_uris oau ON oau.client_id = da.address WHERE - (da.user_id = $1 OR da.address = $2) + (da.user_id = $1 OR lower(da.address) = lower($2)) AND da.is_current = true AND da.is_delete = false GROUP BY da.address, da.user_id, da.name, da.description, da.image_url, da.created_at @@ -84,7 +84,7 @@ SELECT FROM developer_apps LEFT JOIN grants ON grants.grantee_address = developer_apps.address WHERE - (grants.user_id = $1 OR developer_apps.address = $2) + (grants.user_id = $1 OR lower(developer_apps.address) = lower($2)) AND grants.is_revoked = false AND grants.is_current = true AND developer_apps.is_current = true diff --git a/api/dbv1/queries/get_developer_apps.sql b/api/dbv1/queries/get_developer_apps.sql index 4d17c36f..a71e4a15 100644 --- a/api/dbv1/queries/get_developer_apps.sql +++ b/api/dbv1/queries/get_developer_apps.sql @@ -9,7 +9,7 @@ SELECT FROM developer_apps da LEFT JOIN oauth_redirect_uris oau ON oau.client_id = da.address WHERE - (da.user_id = @user_id OR da.address = @address) + (da.user_id = @user_id OR lower(da.address) = lower(@address)) AND da.is_current = true AND da.is_delete = false GROUP BY da.address, da.user_id, da.name, da.description, da.image_url, da.created_at @@ -27,7 +27,7 @@ SELECT FROM developer_apps LEFT JOIN grants ON grants.grantee_address = developer_apps.address WHERE - (grants.user_id = @user_id OR developer_apps.address = @address) + (grants.user_id = @user_id OR lower(developer_apps.address) = lower(@address)) AND grants.is_revoked = false AND grants.is_current = true AND developer_apps.is_current = true From 09d77291c9cfc51f8f01048904dc9bb37efcbca6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Fri, 10 Apr 2026 19:08:01 +0000 Subject: [PATCH 2/3] Normalize address to lowercase in Go, revert lower() from SQL queries Agent-Logs-Url: https://github.com/AudiusProject/api/sessions/9df9ff3f-61bc-492a-bfde-45791942537c Co-authored-by: rickyrombo <3690498+rickyrombo@users.noreply.github.com> --- api/dbv1/get_developer_apps.sql.go | 4 +- api/dbv1/queries/get_developer_apps.sql | 4 +- api/v1_developer_apps.go | 4 ++ api/v1_developer_apps_test.go | 78 ++++++++++++++++++++++++- 4 files changed, 84 insertions(+), 6 deletions(-) diff --git a/api/dbv1/get_developer_apps.sql.go b/api/dbv1/get_developer_apps.sql.go index 438840e6..030fbf83 100644 --- a/api/dbv1/get_developer_apps.sql.go +++ b/api/dbv1/get_developer_apps.sql.go @@ -24,7 +24,7 @@ SELECT FROM developer_apps da LEFT JOIN oauth_redirect_uris oau ON oau.client_id = da.address WHERE - (da.user_id = $1 OR lower(da.address) = lower($2)) + (da.user_id = $1 OR da.address = $2) AND da.is_current = true AND da.is_delete = false GROUP BY da.address, da.user_id, da.name, da.description, da.image_url, da.created_at @@ -84,7 +84,7 @@ SELECT FROM developer_apps LEFT JOIN grants ON grants.grantee_address = developer_apps.address WHERE - (grants.user_id = $1 OR lower(developer_apps.address) = lower($2)) + (grants.user_id = $1 OR developer_apps.address = $2) AND grants.is_revoked = false AND grants.is_current = true AND developer_apps.is_current = true diff --git a/api/dbv1/queries/get_developer_apps.sql b/api/dbv1/queries/get_developer_apps.sql index a71e4a15..4d17c36f 100644 --- a/api/dbv1/queries/get_developer_apps.sql +++ b/api/dbv1/queries/get_developer_apps.sql @@ -9,7 +9,7 @@ SELECT FROM developer_apps da LEFT JOIN oauth_redirect_uris oau ON oau.client_id = da.address WHERE - (da.user_id = @user_id OR lower(da.address) = lower(@address)) + (da.user_id = @user_id OR da.address = @address) AND da.is_current = true AND da.is_delete = false GROUP BY da.address, da.user_id, da.name, da.description, da.image_url, da.created_at @@ -27,7 +27,7 @@ SELECT FROM developer_apps LEFT JOIN grants ON grants.grantee_address = developer_apps.address WHERE - (grants.user_id = @user_id OR lower(developer_apps.address) = lower(@address)) + (grants.user_id = @user_id OR developer_apps.address = @address) AND grants.is_revoked = false AND grants.is_current = true AND developer_apps.is_current = true diff --git a/api/v1_developer_apps.go b/api/v1_developer_apps.go index 1df54b6e..ac0252b2 100644 --- a/api/v1_developer_apps.go +++ b/api/v1_developer_apps.go @@ -18,6 +18,10 @@ func (app *ApiServer) v1DeveloperApps(c *fiber.Ctx) error { address = "0x" + address } + // Normalize address to lowercase to ensure case-insensitive matching + // (addresses in the DB are stored as lowercase) + address = strings.ToLower(address) + developerApps, err := app.queries.GetDeveloperApps(c.Context(), dbv1.GetDeveloperAppsParams{ Address: address, }) diff --git a/api/v1_developer_apps_test.go b/api/v1_developer_apps_test.go index 53cd622e..b12dac5c 100644 --- a/api/v1_developer_apps_test.go +++ b/api/v1_developer_apps_test.go @@ -8,6 +8,8 @@ import ( "github.com/stretchr/testify/assert" ) +const testDeveloperAppAddress = "0x7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6" + func TestGetDeveloperAppsQueries(t *testing.T) { app := testAppWithFixtures(t) developerApps, err := app.queries.GetDeveloperApps(t.Context(), dbv1.GetDeveloperAppsParams{ @@ -15,7 +17,7 @@ func TestGetDeveloperAppsQueries(t *testing.T) { }) assert.NoError(t, err) assert.Len(t, developerApps, 1) - assert.Equal(t, "0x7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6", developerApps[0].Address) + assert.Equal(t, testDeveloperAppAddress, developerApps[0].Address) // redirect_uris must be an empty slice (not nil) when no URIs are registered assert.Equal(t, []string{}, developerApps[0].RedirectUris) } @@ -26,7 +28,7 @@ func TestGetDeveloperApp(t *testing.T) { var resp struct { Data dbv1.GetDeveloperAppsRow } - status, body := testGet(t, app, "/v1/developer_apps/0x7d7b6b7a97d1deefe3a1ccc5a13c48e8f055e0b6", &resp) + status, body := testGet(t, app, "/v1/developer_apps/"+testDeveloperAppAddress, &resp) assert.Equal(t, 200, status) assert.True(t, strings.Contains(string(body), `"user_id":"7eP5n"`)) assert.True(t, strings.Contains(string(body), `"name":"cool app"`)) @@ -34,3 +36,75 @@ func TestGetDeveloperApp(t *testing.T) { // redirect_uris must be an empty slice (not nil) when no URIs are registered assert.Equal(t, []string{}, resp.Data.RedirectUris) } + +func TestGetDeveloperAppUppercaseAddress(t *testing.T) { + app := testAppWithFixtures(t) + + var resp struct { + Data dbv1.GetDeveloperAppsRow + } + // Uppercase address should still find the app (case-insensitive lookup) + status, _ := testGet(t, app, "/v1/developer_apps/0x7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp) + assert.Equal(t, 200, status) + assert.Equal(t, "cool app", resp.Data.Name) +} + +func TestGetDeveloperAppMixedCaseAddress(t *testing.T) { + app := testAppWithFixtures(t) + + var resp struct { + Data dbv1.GetDeveloperAppsRow + } + // Mixed-case address should still find the app (case-insensitive lookup) + status, _ := testGet(t, app, "/v1/developer_apps/0x7d7B6B7A97d1deEFe3A1ccc5A13c48E8F055e0B6", &resp) + assert.Equal(t, 200, status) + assert.Equal(t, "cool app", resp.Data.Name) +} + +func TestGetDeveloperAppWithoutHexPrefix(t *testing.T) { + app := testAppWithFixtures(t) + + var resp struct { + Data dbv1.GetDeveloperAppsRow + } + // Address without 0x prefix should still find the app + status, _ := testGet(t, app, "/v1/developer_apps/7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp) + assert.Equal(t, 200, status) + assert.Equal(t, "cool app", resp.Data.Name) +} + +func TestGetDeveloperAppUppercaseAddress(t *testing.T) { + app := testAppWithFixtures(t) + + var resp struct { + Data dbv1.GetDeveloperAppsRow + } + // Uppercase address should still find the app (case-insensitive lookup) + status, _ := testGet(t, app, "/v1/developer_apps/0x7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp) + assert.Equal(t, 200, status) + assert.Equal(t, "cool app", resp.Data.Name) +} + +func TestGetDeveloperAppMixedCaseAddress(t *testing.T) { + app := testAppWithFixtures(t) + + var resp struct { + Data dbv1.GetDeveloperAppsRow + } + // Mixed-case address should still find the app (case-insensitive lookup) + status, _ := testGet(t, app, "/v1/developer_apps/0x7d7B6B7A97d1deEFe3A1ccc5A13c48E8F055e0B6", &resp) + assert.Equal(t, 200, status) + assert.Equal(t, "cool app", resp.Data.Name) +} + +func TestGetDeveloperAppWithoutHexPrefix(t *testing.T) { + app := testAppWithFixtures(t) + + var resp struct { + Data dbv1.GetDeveloperAppsRow + } + // Address without 0x prefix should still find the app + status, _ := testGet(t, app, "/v1/developer_apps/7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp) + assert.Equal(t, 200, status) + assert.Equal(t, "cool app", resp.Data.Name) +} From 3134346010dfffd0a99ff8fb4861de1914459046 Mon Sep 17 00:00:00 2001 From: Marcus Pasell <3690498+rickyrombo@users.noreply.github.com> Date: Mon, 13 Apr 2026 15:00:48 -0700 Subject: [PATCH 3/3] Remove duplicate test functions in developer apps test Co-Authored-By: Claude Opus 4.6 --- api/v1_developer_apps_test.go | 36 ----------------------------------- 1 file changed, 36 deletions(-) diff --git a/api/v1_developer_apps_test.go b/api/v1_developer_apps_test.go index b12dac5c..8573f8ac 100644 --- a/api/v1_developer_apps_test.go +++ b/api/v1_developer_apps_test.go @@ -72,39 +72,3 @@ func TestGetDeveloperAppWithoutHexPrefix(t *testing.T) { assert.Equal(t, 200, status) assert.Equal(t, "cool app", resp.Data.Name) } - -func TestGetDeveloperAppUppercaseAddress(t *testing.T) { - app := testAppWithFixtures(t) - - var resp struct { - Data dbv1.GetDeveloperAppsRow - } - // Uppercase address should still find the app (case-insensitive lookup) - status, _ := testGet(t, app, "/v1/developer_apps/0x7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp) - assert.Equal(t, 200, status) - assert.Equal(t, "cool app", resp.Data.Name) -} - -func TestGetDeveloperAppMixedCaseAddress(t *testing.T) { - app := testAppWithFixtures(t) - - var resp struct { - Data dbv1.GetDeveloperAppsRow - } - // Mixed-case address should still find the app (case-insensitive lookup) - status, _ := testGet(t, app, "/v1/developer_apps/0x7d7B6B7A97d1deEFe3A1ccc5A13c48E8F055e0B6", &resp) - assert.Equal(t, 200, status) - assert.Equal(t, "cool app", resp.Data.Name) -} - -func TestGetDeveloperAppWithoutHexPrefix(t *testing.T) { - app := testAppWithFixtures(t) - - var resp struct { - Data dbv1.GetDeveloperAppsRow - } - // Address without 0x prefix should still find the app - status, _ := testGet(t, app, "/v1/developer_apps/7D7B6B7A97D1DEEFE3A1CCC5A13C48E8F055E0B6", &resp) - assert.Equal(t, 200, status) - assert.Equal(t, "cool app", resp.Data.Name) -}