-
Notifications
You must be signed in to change notification settings - Fork 484
[Docs][API] - Updates our Docs to allow for project selection on api pages #1058
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Conversation
Older cmux preview screenshots (latest comment is below)Preview ScreenshotsOpen Workspace (1 hr expiry) · Open Dev Browser (1 hr expiry) · Open Diff Heatmap Captured 4 screenshots for commit EnhancedAPIPage component showing POST /auth/password/sign-in endpoint with Request Body fields (email/password), Response section with Expected/Live Response tabs, and Code Examples section AuthPanel component showing API Authentication header with 'logged in' badge, Quick Select Project dropdown, and all header input fields (Access Type, Project ID, Client Key, Server Key, Access Token, Admin Access Token) with '0 configured' status AuthPanel with project dropdown expanded showing available projects (Dummy Project, Stack Dashboard) for quick selection AuthPanel after project selection showing auto-populated headers (Access Type: admin, Project ID: internal, Admin Access Token with JWT), success message, and 'Ready for API requests' status indicator Generated by cmux preview system |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Note Other AI code review bot(s) detectedCodeRabbit has detected other AI code review bot(s) in this pull request and will avoid duplicating their findings in the review comments. This may lead to a less comprehensive review. WalkthroughAdds admin-scoped authentication to the docs API UI: project selection in the auth panel, client-side admin token refresh and propagation into shared headers before requests, updateSharedHeaders API/type changes and behavior tweaks, Content-Type handling notes, and a default "internal" fallback for StackServerApp.projectId. Changes
Sequence Diagram(s)sequenceDiagram
participant Dev as Developer (UI)
participant AuthPanel as Auth Panel
participant User as useUser/session
participant APIPage as Enhanced API Page
participant API as Stack API
Dev->>AuthPanel: open auth panel / select project
AuthPanel->>User: request session / user data
User-->>AuthPanel: return session
AuthPanel->>User: call user.getAuthJson() (get admin token)
User-->>AuthPanel: return auth JSON (admin token)
AuthPanel->>AuthPanel: merge admin headers (X-Stack-Admin-Access-Token, access-type, project-id)
AuthPanel->>APIPage: call updateSharedHeaders(newHeaders)
Dev->>APIPage: trigger API request
APIPage->>APIPage: detect admin access in shared headers
APIPage->>User: call user.getAuthJson() to refresh token
User-->>APIPage: return refreshed token
APIPage->>APIPage: update request headers with refreshed token and Content-Type if JSON
APIPage->>API: send request with admin headers
API-->>APIPage: return response
APIPage-->>Dev: render response
Estimated code review effort🎯 4 (Complex) | ⏱️ ~50 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Greptile OverviewGreptile SummaryAdded project selection dropdown to API docs authentication panel, enabling authenticated users to quickly select and test endpoints against their owned projects using admin authentication. Key Changes
Issues Found
Confidence Score: 3/5
Important Files ChangedFile Analysis
Sequence DiagramsequenceDiagram
participant User
participant AuthPanel
participant EnhancedAPIPage
participant StackAuth
participant API
User->>AuthPanel: Select project from dropdown
AuthPanel->>AuthPanel: handleProjectSelect(projectId)
AuthPanel->>AuthPanel: Update headers with projectId
AuthPanel->>StackAuth: Request user authentication data
StackAuth-->>AuthPanel: Return authentication info
AuthPanel->>AuthPanel: Populate admin authentication header
User->>EnhancedAPIPage: Click Try it out button
EnhancedAPIPage->>EnhancedAPIPage: executeRequest()
alt Admin access type
EnhancedAPIPage->>StackAuth: Request fresh user authentication
StackAuth-->>EnhancedAPIPage: Return fresh authentication info
EnhancedAPIPage->>EnhancedAPIPage: Update admin authentication header
end
EnhancedAPIPage->>EnhancedAPIPage: Build request URL with parameters
EnhancedAPIPage->>EnhancedAPIPage: Prepare headers and body
EnhancedAPIPage->>API: fetch(url, requestOptions)
API-->>EnhancedAPIPage: Response (status, data, headers)
alt Error response (400/401/403)
EnhancedAPIPage->>AuthPanel: reportError(status, error)
AuthPanel->>AuthPanel: Highlight missing headers
AuthPanel->>User: Show error in auth panel
end
EnhancedAPIPage->>User: Display response in UI
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 files reviewed, 2 comments
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🧹 Nitpick comments (3)
docs/src/components/api/auth-panel.tsx (1)
117-124: Strengthen type definitions for header configuration.The
stackAuthHeadersarray uses properties (hideWhenProjectSelected,isSensitive) that aren't in the implicit type, requiring(header as any)casts later. Define an explicit type to improve safety.+type StackAuthHeader = { + key: string; + label: string; + placeholder: string; + required: boolean; + hideWhenProjectSelected?: boolean; + isSensitive?: boolean; +}; - const stackAuthHeaders = [ + const stackAuthHeaders: StackAuthHeader[] = [ { key: 'X-Stack-Access-Type', label: 'Access Type', placeholder: 'client, server, or admin', required: true }, ... ];This eliminates the need for
(header as any)casts on lines 256, 262, 422, and 428.docs/src/components/api/enhanced-api-page.tsx (2)
423-428: Consider extracting duplicated base URL logic.The base URL resolution logic is duplicated in
generateCurlCommand,generateJavaScriptCode, andgeneratePythonCode. Consider extracting to a shared memoized value.+ const computedBaseUrl = useMemo(() => { + const defaultBaseUrl = spec?.servers?.[0]?.url || ''; + return process.env.NEXT_PUBLIC_STACK_API_URL + ? process.env.NEXT_PUBLIC_STACK_API_URL + '/api/v1' + : defaultBaseUrl; + }, [spec]); const generateCurlCommand = useCallback(() => { - // Use local API URL in development, production URL otherwise - const defaultBaseUrl = spec.servers?.[0]?.url || ''; - const baseUrl = process.env.NEXT_PUBLIC_STACK_API_URL - ? process.env.NEXT_PUBLIC_STACK_API_URL + '/api/v1' - : defaultBaseUrl; - let url = baseUrl + path; + let url = computedBaseUrl + path;
371-375: Avoid.catch(console.error)pattern.Per coding guidelines, avoid
.catch(console.error). TheexecuteRequestfunction already handles errors internally, so the outer catch is redundant.onExecute={() => { - // eslint-disable-next-line no-restricted-syntax - executeRequest(operation, path, method) - .catch(error => console.error('Failed to execute request:', error)); + runAsynchronouslyWithAlert(() => executeRequest(operation, path, method)); }}Or if
executeRequestalready handles all errors gracefully, the catch can be removed entirely.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
docs/src/components/api/api-page-wrapper.tsx(1 hunks)docs/src/components/api/auth-panel.tsx(10 hunks)docs/src/components/api/enhanced-api-page.tsx(8 hunks)docs/src/stack.ts(1 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Always add new E2E tests when changing the API or SDK interface
For blocking alerts and errors, never use toast; use alerts instead as they are less easily missed by the user
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error); use loading indicators and async callbacks instead, or use runAsynchronously/runAsynchronouslyWithAlert for error handling
Use ES6 maps instead of records wherever you can
Files:
docs/src/stack.tsdocs/src/components/api/api-page-wrapper.tsxdocs/src/components/api/enhanced-api-page.tsxdocs/src/components/api/auth-panel.tsx
**/*.{ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,css}: Keep hover/click transitions snappy and fast; avoid fade-in delays on hover. Apply transitions after action completion instead, like smooth fade-out when hover ends
Use hover-exit transitions instead of hover-enter transitions; for example, use 'transition-colors hover:transition-none' instead of fade-in on hover
Files:
docs/src/stack.tsdocs/src/components/api/api-page-wrapper.tsxdocs/src/components/api/enhanced-api-page.tsxdocs/src/components/api/auth-panel.tsx
{.env*,**/*.{ts,tsx,js}}
📄 CodeRabbit inference engine (AGENTS.md)
Prefix environment variables with STACK_ (or NEXT_PUBLIC_STACK_ if public) so changes are picked up by Turborepo and improves readability
Files:
docs/src/stack.tsdocs/src/components/api/api-page-wrapper.tsxdocs/src/components/api/enhanced-api-page.tsxdocs/src/components/api/auth-panel.tsx
🧠 Learnings (2)
📚 Learning: 2025-12-04T18:03:49.961Z
Learnt from: CR
Repo: stack-auth/stack-auth PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T18:03:49.961Z
Learning: Applies to {.env*,**/*.{ts,tsx,js}} : Prefix environment variables with STACK_ (or NEXT_PUBLIC_STACK_ if public) so changes are picked up by Turborepo and improves readability
Applied to files:
docs/src/stack.ts
📚 Learning: 2025-10-11T04:13:19.308Z
Learnt from: N2D4
Repo: stack-auth/stack-auth PR: 943
File: examples/convex/app/action/page.tsx:23-28
Timestamp: 2025-10-11T04:13:19.308Z
Learning: In the stack-auth codebase, use `runAsynchronouslyWithAlert` from `stackframe/stack-shared/dist/utils/promises` for async button click handlers and form submissions instead of manual try/catch blocks. This utility automatically handles errors and shows alerts to users.
Applied to files:
docs/src/components/api/enhanced-api-page.tsxdocs/src/components/api/auth-panel.tsx
🧬 Code graph analysis (1)
docs/src/components/api/auth-panel.tsx (1)
docs/src/components/icons.tsx (1)
ChevronDown(67-69)
🪛 Biome (2.1.2)
docs/src/components/api/auth-panel.tsx
[error] 21-21: This hook is being called conditionally, but all hooks must be called in the exact same order in every component render.
For React to preserve state between calls, hooks needs to be called unconditionally and always in the same order.
See https://reactjs.org/docs/hooks-rules.html#only-call-hooks-at-the-top-level
(lint/correctness/useHookAtTopLevel)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (11)
- GitHub Check: all-good
- GitHub Check: Vercel Agent Review
- GitHub Check: check_prisma_migrations (22.x)
- GitHub Check: lint_and_build (latest)
- GitHub Check: setup-tests
- GitHub Check: build (22.x)
- GitHub Check: restart-dev-and-test
- GitHub Check: restart-dev-and-test-with-custom-base-port
- GitHub Check: build (22.x)
- GitHub Check: docker
- GitHub Check: build (22.x)
🔇 Additional comments (2)
docs/src/components/api/api-page-wrapper.tsx (1)
7-15: LGTM!The header configuration changes are well-documented. The comment clarifying Content-Type handling and the addition of
X-Stack-Admin-Access-Tokenfor admin authentication are appropriate for the new project selection feature.docs/src/stack.ts (1)
7-7: LGTM!The fallback to
"internal"ensures the docs app initializes correctly when the environment variable is not set, supporting the shared authentication model between docs and dashboard.
Older cmux preview screenshots (latest comment is below)Preview Screenshots⏳ Preview screenshots are being captured... Workspace and dev browser links will appear here once the preview environment is ready. Generated by cmux preview system |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
♻️ Duplicate comments (1)
docs/src/components/api/auth-panel.tsx (1)
53-57: Conditional hook call still violates Rules of Hooks.Line 55 conditionally calls
useOwnedProjects()using optional chaining (internalUser?.useOwnedProjects()), which still violates React's Rules of Hooks. Hooks must be called unconditionally at the top level.Consider checking if
useOwnedProjectscan be imported as a separate hook and called unconditionally, or ensure it's called at the top level without conditional access.
🧹 Nitpick comments (2)
docs/src/components/api/auth-panel.tsx (1)
328-330: Consider consistent wording across desktop and mobile.Line 330 shows "via project selection" for desktop, while line 497 shows "via project" for mobile. Consider using the same text for consistency, though this is a minor UX detail.
Apply this diff if you prefer consistency:
- {selectedProjectId && ' (via project)'} + {selectedProjectId && ' (via project selection)'}Also applies to: 496-498
docs/src/components/api/enhanced-api-page.tsx (1)
227-230: Consider extracting base URL resolution logic.The base URL resolution logic is duplicated across four locations (lines 227-230, 416-421, 467-471, 521-525). Extracting this into a helper function would improve maintainability.
Add a helper function:
const getBaseUrl = useCallback(() => { const defaultBaseUrl = spec?.servers?.[0]?.url || ''; const localApiUrl = process.env.NEXT_PUBLIC_STACK_API_URL; return localApiUrl ? localApiUrl + '/api/v1' : defaultBaseUrl; }, [spec]);Then replace all four occurrences with
const baseUrl = getBaseUrl();Also applies to: 416-421, 467-471, 521-525
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
docs/src/components/api/auth-panel.tsx(9 hunks)docs/src/components/api/enhanced-api-page.tsx(9 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Always add new E2E tests when changing the API or SDK interface
For blocking alerts and errors, never use toast; use alerts instead as they are less easily missed by the user
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error); use loading indicators and async callbacks instead, or use runAsynchronously/runAsynchronouslyWithAlert for error handling
Use ES6 maps instead of records wherever you can
Files:
docs/src/components/api/auth-panel.tsxdocs/src/components/api/enhanced-api-page.tsx
**/*.{ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,css}: Keep hover/click transitions snappy and fast; avoid fade-in delays on hover. Apply transitions after action completion instead, like smooth fade-out when hover ends
Use hover-exit transitions instead of hover-enter transitions; for example, use 'transition-colors hover:transition-none' instead of fade-in on hover
Files:
docs/src/components/api/auth-panel.tsxdocs/src/components/api/enhanced-api-page.tsx
{.env*,**/*.{ts,tsx,js}}
📄 CodeRabbit inference engine (AGENTS.md)
Prefix environment variables with STACK_ (or NEXT_PUBLIC_STACK_ if public) so changes are picked up by Turborepo and improves readability
Files:
docs/src/components/api/auth-panel.tsxdocs/src/components/api/enhanced-api-page.tsx
🧠 Learnings (2)
📚 Learning: 2025-10-11T04:13:19.308Z
Learnt from: N2D4
Repo: stack-auth/stack-auth PR: 943
File: examples/convex/app/action/page.tsx:23-28
Timestamp: 2025-10-11T04:13:19.308Z
Learning: In the stack-auth codebase, use `runAsynchronouslyWithAlert` from `stackframe/stack-shared/dist/utils/promises` for async button click handlers and form submissions instead of manual try/catch blocks. This utility automatically handles errors and shows alerts to users.
Applied to files:
docs/src/components/api/auth-panel.tsxdocs/src/components/api/enhanced-api-page.tsx
📚 Learning: 2025-12-04T18:03:49.984Z
Learnt from: CR
Repo: stack-auth/stack-auth PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T18:03:49.984Z
Learning: Applies to **/*.{ts,tsx} : NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error); use loading indicators and async callbacks instead, or use runAsynchronously/runAsynchronouslyWithAlert for error handling
Applied to files:
docs/src/components/api/auth-panel.tsx
🧬 Code graph analysis (2)
docs/src/components/api/auth-panel.tsx (5)
docs/src/components/layouts/sidebar-context.tsx (1)
useSidebar(46-49)docs/src/components/api/api-page-wrapper.tsx (1)
useAPIPageContext(38-43)packages/stack-shared/src/utils/promises.tsx (1)
runAsynchronously(343-366)packages/stack-shared/src/utils/strings.tsx (1)
stringCompare(61-65)docs/src/components/icons.tsx (1)
ChevronDown(67-69)
docs/src/components/api/enhanced-api-page.tsx (1)
packages/template/src/lib/stack-app/apps/implementations/common.ts (1)
defaultBaseUrl(145-145)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: Vercel Agent Review
- GitHub Check: check_prisma_migrations (22.x)
- GitHub Check: docker
- GitHub Check: E2E Tests (Node 22.x, Freestyle mock)
- GitHub Check: build (22.x)
- GitHub Check: all-good
- GitHub Check: setup-tests
- GitHub Check: build (22.x)
- GitHub Check: E2E Tests (Node 22.x, Freestyle prod)
- GitHub Check: lint_and_build (latest)
- GitHub Check: restart-dev-and-test-with-custom-base-port
- GitHub Check: setup-tests-with-custom-base-port
- GitHub Check: restart-dev-and-test
🔇 Additional comments (6)
docs/src/components/api/auth-panel.tsx (3)
149-174: LGTM! Clean project selection logic.The project selection handler properly validates the selected project and sets up admin headers. The use of
useMemofor sorting projects is good for performance optimization.
238-268: LGTM! Well-designed project selector UI.The project selector provides good UX with clear labels, success feedback, and proper accessibility. The conditional rendering and sorted project list enhance usability.
271-317: LGTM! Clean auto-population logic.The conditional field visibility and auto-population logic provide a smooth user experience. Making auto-populated fields read-only with clear feedback is a good UX pattern.
docs/src/components/api/enhanced-api-page.tsx (3)
211-225: Admin token refresh logic improved, but silent failure possible.The code no longer directly mutates state (previous issue resolved). However, if
user.getAuthJson()fails, the request proceeds with potentially stale headers. This might be intentional behavior.If token refresh failure should block the request, consider wrapping this logic differently or surfacing the error to the user. Otherwise, the current implementation is acceptable for graceful degradation.
272-277: LGTM! Proper Content-Type header handling.Explicitly adding the Content-Type header when sending JSON ensures proper request formatting. The spread operation correctly preserves existing headers including the refreshed admin token.
316-316: LGTM! Complete dependency array.All dependencies used within the
executeRequestcallback are properly included in the dependency array, including the newly addeduserandupdateSharedHeaders.
Preview Screenshots⏳ Preview screenshots are being captured... Workspace and dev browser links will appear here once the preview environment is ready. Generated by cmux preview system |
…ate support. Updated auth panel admin-token refresh effect to rely on the new functional updater and trimmed its dependency list, preventing the previous infinite loop that caused maximum update depth exceeded
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
docs/src/components/api/auth-panel.tsx (1)
53-57: Conditional hook call violates Rules of Hooks.Line 55 calls
useOwnedProjects()conditionally via optional chaining (internalUser?.useOwnedProjects()). IfinternalUserisnullon one render and non-null on the next, the hook call order changes, violating React's Rules of Hooks.Refactor to call the hook unconditionally:
- const user = useUser(); - const internalUser = isInternalUser(user) ? user : null; - const ownedProjectsResult = internalUser?.useOwnedProjects(); - const projects = useMemo<AdminOwnedProject[]>(() => ownedProjectsResult ?? [], [ownedProjectsResult]); - const hasOwnedProjects = Boolean(internalUser); + const user = useUser(); + const internalUser = isInternalUser(user) ? user : null; + // Always call the hook unconditionally - pass internalUser to satisfy hook rules + const ownedProjectsResult = internalUser ? internalUser.useOwnedProjects() : null; + const projects = useMemo<AdminOwnedProject[]>(() => ownedProjectsResult ?? [], [ownedProjectsResult]); + const hasOwnedProjects = Boolean(internalUser);Actually, the issue persists with ternary too. The hook must be called at the top level unconditionally. Consider restructuring by either:
- Always calling
useOwnedProjectsfrom a stable source (if it's a standalone hook)- Creating a child component that only renders when
internalUserexists, which can safely call the hook
🧹 Nitpick comments (3)
docs/src/components/api/auth-panel.tsx (3)
142-143: Dead code: ternary always returns the same value.The
topPositioncalculation always evaluates to'top-0'regardless of the condition.- const topPosition = isHomePage && isScrolled ? 'top-0' : 'top-0'; + const topPosition = 'top-0';
149-169: Consider using functional update for consistency.The
handleProjectSelectspreadsheadersdirectly while theuseEffectuses functional updates. For consistency and to avoid potential stale closure issues if this function is ever used in callbacks:- const newHeaders = { - ...headers, - 'X-Stack-Access-Type': 'admin', - 'X-Stack-Project-Id': projectId, - 'X-Stack-Admin-Access-Token': '', // Will be populated by refresh effect - 'X-Stack-Access-Token': '', // Not used for admin access - 'X-Stack-Publishable-Client-Key': '', // Not needed for admin auth - 'X-Stack-Secret-Server-Key': '', // Not needed for admin auth - }; - - updateSharedHeaders(newHeaders); + updateSharedHeaders(prevHeaders => ({ + ...prevHeaders, + 'X-Stack-Access-Type': 'admin', + 'X-Stack-Project-Id': projectId, + 'X-Stack-Admin-Access-Token': '', // Will be populated by refresh effect + 'X-Stack-Access-Token': '', // Not used for admin access + 'X-Stack-Publishable-Client-Key': '', // Not needed for admin auth + 'X-Stack-Secret-Server-Key': '', // Not needed for admin auth + }));
304-304: Consider functional update for input onChange handlers.For consistency with the
useEffectpattern and to ensure the latest headers are used:- onChange={(e) => updateSharedHeaders({ ...headers, [header.key]: e.target.value })} + onChange={(e) => updateSharedHeaders(prev => ({ ...prev, [header.key]: e.target.value }))}Same applies to line 470 (mobile input).
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
docs/src/components/api/api-page-wrapper.tsx(3 hunks)docs/src/components/api/auth-panel.tsx(9 hunks)
🧰 Additional context used
📓 Path-based instructions (3)
**/*.{ts,tsx}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx}: Always add new E2E tests when changing the API or SDK interface
For blocking alerts and errors, never use toast; use alerts instead as they are less easily missed by the user
NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error); use loading indicators and async callbacks instead, or use runAsynchronously/runAsynchronouslyWithAlert for error handling
Use ES6 maps instead of records wherever you can
Files:
docs/src/components/api/auth-panel.tsxdocs/src/components/api/api-page-wrapper.tsx
**/*.{ts,tsx,css}
📄 CodeRabbit inference engine (AGENTS.md)
**/*.{ts,tsx,css}: Keep hover/click transitions snappy and fast; avoid fade-in delays on hover. Apply transitions after action completion instead, like smooth fade-out when hover ends
Use hover-exit transitions instead of hover-enter transitions; for example, use 'transition-colors hover:transition-none' instead of fade-in on hover
Files:
docs/src/components/api/auth-panel.tsxdocs/src/components/api/api-page-wrapper.tsx
{.env*,**/*.{ts,tsx,js}}
📄 CodeRabbit inference engine (AGENTS.md)
Prefix environment variables with STACK_ (or NEXT_PUBLIC_STACK_ if public) so changes are picked up by Turborepo and improves readability
Files:
docs/src/components/api/auth-panel.tsxdocs/src/components/api/api-page-wrapper.tsx
🧠 Learnings (2)
📚 Learning: 2025-10-11T04:13:19.308Z
Learnt from: N2D4
Repo: stack-auth/stack-auth PR: 943
File: examples/convex/app/action/page.tsx:23-28
Timestamp: 2025-10-11T04:13:19.308Z
Learning: In the stack-auth codebase, use `runAsynchronouslyWithAlert` from `stackframe/stack-shared/dist/utils/promises` for async button click handlers and form submissions instead of manual try/catch blocks. This utility automatically handles errors and shows alerts to users.
Applied to files:
docs/src/components/api/auth-panel.tsx
📚 Learning: 2025-12-04T18:03:49.984Z
Learnt from: CR
Repo: stack-auth/stack-auth PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-04T18:03:49.984Z
Learning: Applies to **/*.{ts,tsx} : NEVER try-catch-all, NEVER void a promise, and NEVER .catch(console.error); use loading indicators and async callbacks instead, or use runAsynchronously/runAsynchronouslyWithAlert for error handling
Applied to files:
docs/src/components/api/auth-panel.tsx
🧬 Code graph analysis (1)
docs/src/components/api/auth-panel.tsx (5)
docs/src/components/layouts/sidebar-context.tsx (1)
useSidebar(46-49)docs/src/components/api/api-page-wrapper.tsx (1)
useAPIPageContext(40-45)packages/stack-shared/src/utils/promises.tsx (1)
runAsynchronously(343-366)packages/stack-shared/src/utils/strings.tsx (1)
stringCompare(61-65)docs/src/components/icons.tsx (1)
ChevronDown(67-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (13)
- GitHub Check: Vercel Agent Review
- GitHub Check: build (22.x)
- GitHub Check: restart-dev-and-test-with-custom-base-port
- GitHub Check: setup-tests
- GitHub Check: restart-dev-and-test
- GitHub Check: E2E Tests (Node 22.x, Freestyle prod)
- GitHub Check: E2E Tests (Node 22.x, Freestyle mock)
- GitHub Check: setup-tests-with-custom-base-port
- GitHub Check: all-good
- GitHub Check: lint_and_build (latest)
- GitHub Check: check_prisma_migrations (22.x)
- GitHub Check: docker
- GitHub Check: build (22.x)
🔇 Additional comments (4)
docs/src/components/api/api-page-wrapper.tsx (2)
63-71: Well-implemented functional update pattern for shared headers.The
useCallbackwrapper with empty dependencies is correct since React state setters are stable. The functional update support nicely prevents stale closure issues when consumers need to update headers based on current state.
27-31: Clean type extension for functional updates.The
UpdateSharedHeadersInputunion type properly supports both direct object replacement and functional updates, aligning well with React'ssetStatepatterns.docs/src/components/api/auth-panel.tsx (2)
89-106: Good fix for the token refresh effect.The refactored implementation correctly:
- Uses
runAsynchronouslyfor error handling (per coding guidelines)- Uses functional update pattern to avoid stale
headersclosure- Only includes stable dependencies (
updateSharedHeadersis now memoized)This properly addresses the previous review feedback about infinite loops and error handling.
238-268: Good UX for project selection with clear visual feedback.The project selector provides clear indication of logged-in state, sorted projects, and confirmation when headers are auto-populated. The
readOnlystate with visual styling for auto-populated fields is well-handled.
| setSelectedProjectId(projectId); | ||
|
|
||
| if (!projects.some((projectItem) => projectItem.id === projectId)) { | ||
| return; | ||
| } | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| setSelectedProjectId(projectId); | |
| if (!projects.some((projectItem) => projectItem.id === projectId)) { | |
| return; | |
| } | |
| // Validate project exists before modifying state | |
| if (!projects.some((projectItem) => projectItem.id === projectId)) { | |
| return; | |
| } | |
| setSelectedProjectId(projectId); | |
In handleProjectSelect, the component sets selectedProjectId state before validating if the project exists. If validation fails, the function returns early without updating headers, leaving the component in an inconsistent state.
View Details
Analysis
Race condition in AuthPanel.handleProjectSelect() leaves component in inconsistent state
What fails: When a project list update occurs between dropdown render and user selection, handleProjectSelect() sets selectedProjectId state before validating if the project exists, causing the component to enter an inconsistent state where headers lack the required access-type and project-id fields even though the admin access token is fetched.
How to reproduce:
- User views projects [A, B, C] in the Quick Select Project dropdown
- User clicks to select project A
- Before the onChange handler fires, the projects list updates to [B, C, D] (e.g., from a network fetch completing)
- handleProjectSelect fires with projectId="A" but "A" is no longer in the current projects array
- Validation fails and function returns early
- Result: selectedProjectId is set to "A", useEffect fetches admin token, but X-Stack-Access-Type and X-Stack-Project-Id headers were never set
Expected behavior: Validation should occur before state is modified. Invalid project selections should not update state, preventing the component from entering an inconsistent state.
Root cause: In docs/src/components/api/auth-panel.tsx, the handleProjectSelect function calls setSelectedProjectId(projectId) before validating whether the project exists in the projects array. If validation fails and the function returns early, the state remains modified while headers are not updated, leading to incomplete authentication headers.
Fix: Move the validation check to occur before state modification, ensuring that setSelectedProjectId() is only called when the project ID is confirmed to be valid.
Updates the Auth panel on API pages to allow for authenticated users to select a project from project drop downs.
This enables easy access for the user to select their project, and test endpoints against it.
Summary by CodeRabbit
New Features
Improvements
UX
✏️ Tip: You can customize this high-level summary in your review settings.