fix(auth): allow unauthenticated user_id on /feed/for-you#804
Merged
Conversation
The For You handler treats the path :userId as the personalization target and the user_id query param as a viewer hint used only for response decoration (has_current_user_reposted, etc.). It already calls tryGetAuthedWallet (optional), so the handler is happy with an unauthenticated request — but the global authMiddleware returns 403 whenever user_id is set and the request isn't signed, blocking the call before it reaches the handler. Exempt the /feed/for-you route from that strict check. The path :userId still controls what content is returned and access-gated tracks are still filtered out when authedWallet is empty, so the security shape is unchanged for this read endpoint. Adds TestV1FeedForYou_UnauthenticatedViewerIdAllowed which exercises the exemption with skipAuthCheck OFF (so the real auth path runs). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced May 13, 2026
dylanjeffers
added a commit
that referenced
this pull request
May 13, 2026
## Summary
Retiring the dedicated For You feed endpoint. The clients are being
switched to use \`/v1/users/{id}/recommended-tracks\` instead — the same
endpoint that already powers the Explore page's For You section and
works fine in production. See companion PR: AudiusProject/apps#14301.
## Why
The custom \`/feed/for-you\` endpoint had repeated issues since it
shipped:
* **Auth gate bug** (fixed in #804) — global authMiddleware rejected
unsigned \`user_id\` requests, making the endpoint unreachable from the
web RC.
* **Perf** — even after #805 and #806 capped the \`my_saved_artists\`,
\`my_artist_affinity\`, and \`follow_set\` CTEs, EXPLAIN on prod showed
the \`similar_artists\` self-join still produced a 301M-row merge for
power users (and a fixed ~12s \`track_trending_scores\` scan for *every*
user due to a missing partial index). The endpoint never reliably
completed within Cloudflare's 100s upstream limit for power users.
* **Duplication** — the response shape (ranked track list for the
signed-in user) is already what \`/recommended-tracks\` returns. Two
endpoints solving the same problem isn't worth maintaining.
Consolidating on the working endpoint is simpler than continuing to
optimize the custom one.
## Removed
| File | What |
|---|---|
| \`api/v1_users_feed_for_you.go\` | Handler + the 200-row
candidate-pool SQL (4 candidate sources, similar_artists CF, diversity
pass) |
| \`api/v1_users_feed_for_you_test.go\` | 9 unit tests |
| \`api/server.go\` (1 line) | Route registration |
| \`api/auth_middleware.go\` (~10 lines) | The \`/feed/for-you\`
exemption from #804 — no longer needed |
| \`api/swagger/swagger-v1.yaml\` (~70 lines) | The endpoint's swagger
entry |
## Test plan
- ✅ \`go build ./api/...\` clean
- ✅ \`go vet ./api/...\` clean
- ✅ All remaining \`TestV1UsersFeed*\` / \`TestAuth*\` tests pass
locally
- After merge + deploy + AudiusProject/apps#14301 deploy: Feed → For You
tab on the web RC should show the same recommended tracks as Explore's
For You section.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The For You handler (
v1_users_feed_for_you.go) treats::userIdas the personalization targetuser_idas a viewer hint, used only to decorate response fields likehas_current_user_reposted/has_current_user_savedIt already calls
tryGetAuthedWallet(optional), so the handler is fine with an unauthenticated request — the path:userIdcontrols the personalization SQL, and the access-gated track filter falls through to "ungated only" whenauthedWalletis empty.But the global
authMiddlewarereturns 403 wheneveruser_idis set and the request isn't signed:…so the call dies before reaching the handler. Symptom on the web RC: For You tab silently empty / 403 in network tab.
Fix
Exempt the
/feed/for-youroute from that strict check viastrings.HasSuffix(c.Path(), "/feed/for-you"). ThemyIdis still resolved (so viewer-relative fields populate when auser_idis supplied) — it's just not gated behind a wallet match.What stays the same
:userIdstill controls what content is returned — caller can't impersonate a different user for personalization.authedWalletis empty (handler's existingt.access_authoritiespredicate).Test plan
TestV1FeedForYou_UnauthenticatedViewerIdAllowedexercises the exemption withskipAuthCheckOFF (so the real auth path runs). Passes locally against the test DB.TestV1FeedForYou_Basic,TestV1FeedForYou_RequiresValidUserId,TestV1FeedForYou_ExcludesAlreadySavedTracks, etc.).go build ./api/.../go vet ./api/...clean./v1/users/{id}/feed/for-you?user_id={id}should return 200 instead of 403 — verifiable directly with curl.🤖 Generated with Claude Code