feat(cmd-k): Add DSN lookup to both command palettes#108396
feat(cmd-k): Add DSN lookup to both command palettes#108396
Conversation
Add a DSN lookup feature that resolves a pasted DSN to its project and shows quick navigation links (issues, settings, client keys). Works in both the new supercharged palette and the old deprecated one. Gated behind the `cmd-k-dsn-lookup` feature flag.
|
🚨 Warning: This pull request contains Frontend and Backend changes! It's discouraged to make changes to Sentry's Frontend and Backend in a single pull request. The Frontend and Backend are not atomically deployed. If the changes are interdependent of each other, they must be separated into two pull requests and be made forward or backwards compatible, such that the Backend or Frontend can be safely deployed independently. Have questions? Please ask in the |
|
Closing this PR to split into separate backend and frontend PRs, as CI flagged that they should be deployed independently.
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| if (!hasDsnLookup || !isDsn) { | ||
| setData(null); | ||
| return undefined; | ||
| } |
There was a problem hiding this comment.
isLoading stuck true after DSN query changes
Medium Severity
When isDsn transitions from true to false (e.g., user pastes a DSN then deletes part of it), the early-return path calls setData(null) but never calls setIsLoading(false). The cleanup function from the prior effect run sets cancelled = true, preventing the in-flight request's .then()/.catch() from resetting the loading state. This leaves isLoading permanently stuck at true, which causes SearchSources to compute allLoaded as false. If the user clears the input before results arrive, a permanent loading spinner appears in the deprecated command palette.
| projectId: string; | ||
| projectName: string; | ||
| projectPlatform: string | null; | ||
| projectSlug: string; |
There was a problem hiding this comment.
Duplicated DSN pattern and response interface
Low Severity
DSN_PATTERN and DsnLookupResponse are identically defined in both dsnLookupSource.tsx and useDsnLookupActions.tsx. If someone updates the regex or interface in one file but not the other, the two command palettes will silently diverge in behavior. These could be extracted into a shared module.
Additional Locations (1)
## Summary
Adds a private API endpoint that resolves a Sentry DSN to its associated
project and key metadata. This powers the command palette (Cmd+K) —
users can paste a DSN and quickly navigate to the corresponding project.
**Endpoint:** `GET /api/0/organizations/{org}/dsn-lookup/?dsn=<dsn>`
**Behavior:**
- Parses the DSN to extract the public key, then looks up the matching
`ProjectKey` scoped to the requesting organization
- Returns project slug, ID, name, platform, and key label/ID
- Returns 404 for invalid DSNs, unknown keys, or keys belonging to
projects outside the org
**Access control:**
- `OrganizationEndpoint` base class enforces org membership
- `ProjectKey` query is scoped by `project__organization_id` to prevent
IDOR
- Gated behind the `organizations:cmd-k-dsn-lookup` feature flag
- Rate limited to 5 req/s per user
## Context
Split from #108396 — this is the backend half. The frontend PR (command
palette integration) will follow and reference this PR as a dependency.
## Test plan
- [x] Backend tests pass (`pytest
tests/sentry/api/endpoints/test_dsn_lookup.py`)
- [ ] CI passes
---------
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
## Summary
Adds a private API endpoint that resolves a Sentry DSN to its associated
project and key metadata. This powers the command palette (Cmd+K) —
users can paste a DSN and quickly navigate to the corresponding project.
**Endpoint:** `GET /api/0/organizations/{org}/dsn-lookup/?dsn=<dsn>`
**Behavior:**
- Parses the DSN to extract the public key, then looks up the matching
`ProjectKey` scoped to the requesting organization
- Returns project slug, ID, name, platform, and key label/ID
- Returns 404 for invalid DSNs, unknown keys, or keys belonging to
projects outside the org
**Access control:**
- `OrganizationEndpoint` base class enforces org membership
- `ProjectKey` query is scoped by `project__organization_id` to prevent
IDOR
- Gated behind the `organizations:cmd-k-dsn-lookup` feature flag
- Rate limited to 5 req/s per user
## Context
Split from #108396 — this is the backend half. The frontend PR (command
palette integration) will follow and reference this PR as a dependency.
## Test plan
- [x] Backend tests pass (`pytest
tests/sentry/api/endpoints/test_dsn_lookup.py`)
- [ ] CI passes
---------
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
<img width="639" height="242" alt="CleanShot 2026-02-17 at 17 23 35" src="https://github.com/user-attachments/assets/7d7dcc8e-6f6a-4ff1-a442-d65c01aba631" /> ## Summary - Adds DSN lookup to the new supercharged command palette (`useDsnLookupActions` hook) - Adds DSN lookup to the legacy search modal (`dsnLookupSource`) - Users can paste a DSN and quickly navigate to the corresponding project ## Dependencies - **Requires #108400** (backend API endpoint) to be merged first - Frontend gracefully handles missing endpoint — API 404 results in no results shown ## Context Split from #108396 — this is the frontend half. ## Test plan - [x] Frontend tests pass (`CI=true pnpm test useDsnLookupActions`) - [ ] CI passes - [ ] Manual QA after backend PR lands
<img width="639" height="242" alt="CleanShot 2026-02-17 at 17 23 35" src="https://github.com/user-attachments/assets/7d7dcc8e-6f6a-4ff1-a442-d65c01aba631" /> ## Summary - Adds DSN lookup to the new supercharged command palette (`useDsnLookupActions` hook) - Adds DSN lookup to the legacy search modal (`dsnLookupSource`) - Users can paste a DSN and quickly navigate to the corresponding project ## Dependencies - **Requires #108400** (backend API endpoint) to be merged first - Frontend gracefully handles missing endpoint — API 404 results in no results shown ## Context Split from #108396 — this is the frontend half. ## Test plan - [x] Frontend tests pass (`CI=true pnpm test useDsnLookupActions`) - [ ] CI passes - [ ] Manual QA after backend PR lands
## Summary
Adds a private API endpoint that resolves a Sentry DSN to its associated
project and key metadata. This powers the command palette (Cmd+K) —
users can paste a DSN and quickly navigate to the corresponding project.
**Endpoint:** `GET /api/0/organizations/{org}/dsn-lookup/?dsn=<dsn>`
**Behavior:**
- Parses the DSN to extract the public key, then looks up the matching
`ProjectKey` scoped to the requesting organization
- Returns project slug, ID, name, platform, and key label/ID
- Returns 404 for invalid DSNs, unknown keys, or keys belonging to
projects outside the org
**Access control:**
- `OrganizationEndpoint` base class enforces org membership
- `ProjectKey` query is scoped by `project__organization_id` to prevent
IDOR
- Gated behind the `organizations:cmd-k-dsn-lookup` feature flag
- Rate limited to 5 req/s per user
## Context
Split from #108396 — this is the backend half. The frontend PR (command
palette integration) will follow and reference this PR as a dependency.
## Test plan
- [x] Backend tests pass (`pytest
tests/sentry/api/endpoints/test_dsn_lookup.py`)
- [ ] CI passes
---------
Co-authored-by: getsantry[bot] <66042841+getsantry[bot]@users.noreply.github.com>
<img width="639" height="242" alt="CleanShot 2026-02-17 at 17 23 35" src="https://github.com/user-attachments/assets/7d7dcc8e-6f6a-4ff1-a442-d65c01aba631" /> ## Summary - Adds DSN lookup to the new supercharged command palette (`useDsnLookupActions` hook) - Adds DSN lookup to the legacy search modal (`dsnLookupSource`) - Users can paste a DSN and quickly navigate to the corresponding project ## Dependencies - **Requires #108400** (backend API endpoint) to be merged first - Frontend gracefully handles missing endpoint — API 404 results in no results shown ## Context Split from #108396 — this is the frontend half. ## Test plan - [x] Frontend tests pass (`CI=true pnpm test useDsnLookupActions`) - [ ] CI passes - [ ] Manual QA after backend PR lands


Summary
/dsn-lookup/API endpoint that resolves a DSN to its project info (name, slug, org, key ID)useDsnLookupActionshookDsnLookupSourcesearch sourcecmd-k-dsn-lookupfeature flagWhen a user pastes a DSN into either Cmd+K palette, they get 3 results:
Test plan
CI=true pnpm test static/app/components/commandPalette/useDsnLookupActions.spec.tsxpassespytest tests/sentry/api/endpoints/test_dsn_lookup.pycmd-k-superchargedoff,cmd-k-dsn-lookupon