admin: read admin_path_prefix from /auth/me + build admin URLs from it#48
Merged
Merged
Conversation
Pairs with api PR for ADMIN_PATH_PREFIX. The admin customer-management
endpoints now live under /api/v1/<prefix>/customers/... rather than the
guessable /api/v1/admin/customers/... — the prefix is a 32+ char alnum
secret with the same blast radius as a session token.
Changes:
- AuthMeResponse extended with admin_path_prefix?: string.
- fetchMe() stashes the value in a module-local var; logout() clears it.
- getAdminPathPrefix() + setAdminPathPrefix() exported for tests + the
route gate; buildAdminURL() is the single point that turns the stash
into a request path.
- The 4 admin API functions (listAdminCustomers, getAdminCustomer,
setAdminCustomerTier, issueAdminCustomerPromo) call buildAdminURL()
instead of hardcoding /api/v1/admin/. With no prefix loaded, every
builder throws APIError{status:403, code:"admin_endpoints_unavailable"}.
- AdminCustomersPage's gate is now is_platform_admin AND admin_path_prefix
(belt-and-braces — flag-without-prefix would render a broken page).
- AppShell hides the sidebar link under the same compound condition.
- The prefix is treated as a credential: never logged, never echoed
into rendered UI text.
Tests: 6 new unit tests in api/index.test.ts cover the stash/clear/
URL-build/throw paths; existing 382 unit tests still pass; tsc clean.
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
Pairs with api PR #50. The admin customer-management endpoints now register on the agent API under
/api/v1/<prefix>/customers/...where<prefix>is a 32+ char alphanumeric secret with the same blast radius as a session token. This PR teaches the dashboard to read the prefix from/auth/meand build the URLs from it client-side.Changes:
AuthMeResponseextended withadmin_path_prefix?: string.fetchMe()stashes the value in a module-local var;logout()clears it.getAdminPathPrefix()+setAdminPathPrefix()are the only public read/write seams;buildAdminURL()is the single point that turns the stash into a request path.listAdminCustomers,getAdminCustomer,setAdminCustomerTier,issueAdminCustomerPromo) callbuildAdminURL()instead of hardcoding/api/v1/admin/. With no prefix loaded, every builder throwsAPIError{status:403, code:"admin_endpoints_unavailable"}.AdminCustomersPage's route gate is nowis_platform_admin && admin_path_prefix(belt-and-braces — the flag without a prefix would render a broken page).AppShellhides the sidebar link under the same compound condition.Test plan
npm test— 382/382 unit tests pass (17 test files); 6 new tests insrc/api/index.test.ts:fetchMe stashes admin_path_prefix when the API serves itfetchMe leaves the prefix empty when the API omits the fieldlogout clears the stashed admin prefixadmin builders mint /api/v1/<prefix>/customers when the prefix is setadmin builders throw admin_endpoints_unavailable when the prefix is emptyadmin builders never include /admin/ in the request URL(covers the "prefix contains 'admin' substring" edge case)npx tsc --noEmit— cleanAdminCustomersPage.test.tsxmock updated to surfaceadmin_path_prefixso the page gate sees both signals/auth/me; non-admin user verifies the sidebar link is hidden and direct navigation to/app/admin/customersredirects to/🤖 Generated with Claude Code