Skip to content

refactor: unify auth and sandbox next proxies#407

Merged
jerry609 merged 1 commit intodevfrom
refactor/pr12-next-proxy-remaining
Mar 15, 2026
Merged

refactor: unify auth and sandbox next proxies#407
jerry609 merged 1 commit intodevfrom
refactor/pr12-next-proxy-remaining

Conversation

@jerry609
Copy link
Owner

What changed

  • expand web/src/app/api/_utils/backend-proxy.ts into a shared JSON/text proxy layer with timeout handling, upstream error fallbacks, and unified backend base URL resolution
  • migrate auth proxy routes (forgot-password, register, reset-password, me, me/change-password, login-check) to the shared helper
  • migrate sandbox/status to the same helper and add focused helper tests for auth passthrough, empty 204 responses, and custom 502 fallbacks

Why

  • removes duplicated Next API proxy logic and aligns auth/sandbox routes on one contract
  • keeps this PR limited to non-streaming, non-binary proxy routes so review stays small
  • leaves streaming/download/fallback-specialized routes for follow-up PRs

Validation

  • npx vitest run src/app/api/_utils/backend-proxy.test.ts src/app/api/_utils/auth-headers.test.ts src/app/api/papers/export/route.test.ts
  • npx eslint src/app/api/_utils/backend-proxy.ts src/app/api/_utils/backend-proxy.test.ts src/app/api/auth/forgot-password/route.ts src/app/api/auth/register/route.ts src/app/api/auth/reset-password/route.ts src/app/api/auth/me/change-password/route.ts src/app/api/auth/me/route.ts src/app/api/auth/login-check/route.ts src/app/api/sandbox/status/route.ts
  • npx tsc --noEmit
  • npm run build

Follow-up

  • remaining direct backend fetch routes are now the streaming/download/html-fallback/no-store cases and should land as separate PRs

Copilot AI review requested due to automatic review settings March 15, 2026 07:02
@vercel
Copy link

vercel bot commented Mar 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
paper-bot Ready Ready Preview, Comment Mar 15, 2026 7:03am

@coderabbitai
Copy link

coderabbitai bot commented Mar 15, 2026

Warning

Rate limit exceeded

@jerry609 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 9 minutes and 8 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: f519610c-46fd-49f4-8535-50719f780839

📥 Commits

Reviewing files that changed from the base of the PR and between 5a02ab3 and 8f0679e.

📒 Files selected for processing (9)
  • web/src/app/api/_utils/backend-proxy.test.ts
  • web/src/app/api/_utils/backend-proxy.ts
  • web/src/app/api/auth/forgot-password/route.ts
  • web/src/app/api/auth/login-check/route.ts
  • web/src/app/api/auth/me/change-password/route.ts
  • web/src/app/api/auth/me/route.ts
  • web/src/app/api/auth/register/route.ts
  • web/src/app/api/auth/reset-password/route.ts
  • web/src/app/api/sandbox/status/route.ts
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch refactor/pr12-next-proxy-remaining
📝 Coding Plan
  • Generate coding plan for human review comments

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request significantly refactors the application's API proxy infrastructure by centralizing common proxy logic into a single, shared utility. The primary goal is to eliminate redundant code, standardize how API requests are forwarded to the backend, and introduce essential features like request timeouts and custom error handling. This consolidation improves consistency, simplifies future development of new proxy routes, and enhances the overall robustness of the application's interaction with its backend services.

Highlights

  • Shared Proxy Layer Expansion: Expanded web/src/app/api/_utils/backend-proxy.ts into a comprehensive shared JSON/text proxy layer. This new utility includes robust features such as timeout handling, upstream error fallbacks, and unified backend base URL resolution, significantly enhancing the reliability and maintainability of API proxy routes.
  • Authentication Routes Migration: Migrated all authentication-related proxy routes, including forgot-password, register, reset-password, me, me/change-password, and login-check, to utilize the newly established shared backend-proxy helper. This ensures consistent behavior and reduces code duplication across these critical routes.
  • Sandbox Status Route Migration and Enhanced Testing: Migrated the sandbox/status route to the shared proxy helper and introduced focused helper tests. These tests specifically validate auth passthrough, correct handling of empty 204 responses, and the functionality of custom 502 fallbacks, ensuring the proxy behaves as expected under various conditions.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • web/src/app/api/_utils/backend-proxy.test.ts
    • Updated apiBaseUrl test to use the shared backend URL helper.
    • Added proxyJson tests for authenticated writes, 204 responses, and custom error handling.
    • Refactored test setup to use backendBaseUrlMock.
  • web/src/app/api/_utils/backend-proxy.ts
    • Introduced ProxyMethod type for HTTP methods.
    • Defined ProxyErrorContext and ProxyOptions types for enhanced error and configuration handling.
    • Added DEFAULT_TIMEOUT_MS constant for request timeouts.
    • Updated apiBaseUrl to use backendBaseUrl from auth-headers.
    • Implemented proxyJson as a wrapper around proxyText for JSON-specific proxying.
    • Refactored proxyText to use new helper functions (fetchUpstream, resolveHeaders, resolveBody, buildTextResponse, handleProxyError).
    • Added timeout logic using AbortController in fetchUpstream.
    • Implemented resolveHeaders to dynamically set headers including Accept and Content-Type, and handle authentication.
    • Created resolveBody to correctly extract request body for non-GET/HEAD methods.
    • Developed buildTextResponse to construct responses, handling 204 status and content types.
    • Introduced handleProxyError for centralized error management, including timeout detection and custom error responses.
  • web/src/app/api/auth/forgot-password/route.ts
    • Refactored POST handler to use the proxyJson helper.
  • web/src/app/api/auth/login-check/route.ts
    • Refactored POST handler to use the proxyJson helper with a custom onError fallback.
  • web/src/app/api/auth/me/change-password/route.ts
    • Refactored POST handler to use the proxyJson helper with authentication enabled.
  • web/src/app/api/auth/me/route.ts
    • Refactored GET, PATCH, and DELETE handlers to use the proxyJson helper with authentication enabled.
  • web/src/app/api/auth/register/route.ts
    • Refactored POST handler to use the proxyJson helper.
  • web/src/app/api/auth/reset-password/route.ts
    • Refactored POST handler to use the proxyJson helper.
  • web/src/app/api/sandbox/status/route.ts
    • Refactored GET handler to use the proxyJson helper.
Activity
  • Initial commit of the pull request.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for GitHub and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

Vercel Preview

@sonarqubecloud
Copy link

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a significant and valuable refactoring by unifying the backend API proxy logic into a shared module. The new proxyJson and proxyText helpers in backend-proxy.ts are well-designed, adding important features like request timeouts, custom error handlers, and proper handling of 204 responses. Migrating the auth and sandbox API routes to these helpers has greatly simplified their code and improved consistency.

I have a couple of suggestions to further improve the new proxy module, primarily around security and flexibility. One is a high-severity issue regarding potential information disclosure in the default error handling. The other is a medium-severity suggestion to make the caching behavior more flexible. Overall, this is a solid improvement to the codebase.

Comment on lines +170 to +180
const detail = error instanceof Error ? error.message : String(error)

return Response.json(
{
detail: isTimeout
? `Upstream API timed out: ${upstreamUrl}`
: `Upstream API unreachable: ${upstreamUrl}`,
error: detail,
},
{ status: 502 },
)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The default error handler exposes internal error details to the client via the error field in the JSON response. This is a potential information disclosure vulnerability, as it could leak sensitive information about the infrastructure. It's safer to return a generic error message to the client and log the specific error on the server for debugging purposes.

Suggested change
const detail = error instanceof Error ? error.message : String(error)
return Response.json(
{
detail: isTimeout
? `Upstream API timed out: ${upstreamUrl}`
: `Upstream API unreachable: ${upstreamUrl}`,
error: detail,
},
{ status: 502 },
)
// The original error should be logged on the server for debugging.
// console.error(`[backend-proxy] Upstream fetch to ${upstreamUrl} failed:`, error);
return Response.json(
{
detail: isTimeout
? `Upstream API timed out: ${upstreamUrl}`
: `Upstream API unreachable: ${upstreamUrl}`,
},
{ status: 502 },
)

options: Pick<TextProxyOptions, "responseContentType" | "responseHeaders">,
): Response {
const headers = new Headers(options.responseHeaders)
headers.set("Cache-Control", "no-cache")

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Hardcoding Cache-Control: no-cache might be too restrictive. It prevents caching of proxied responses, even if the upstream API sends its own caching headers. Consider respecting the upstream's Cache-Control header if it's present, and only falling back to no-cache as a default. This would make the proxy helper more flexible and allow leveraging backend caching strategies.

Suggested change
headers.set("Cache-Control", "no-cache")
if (upstream.headers.has("Cache-Control")) {
headers.set("Cache-Control", upstream.headers.get("Cache-Control")!)
} else {
headers.set("Cache-Control", "no-cache")
}

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors the Next.js API proxy layer to centralize backend URL resolution and request/response handling, then migrates auth and sandbox proxy routes onto the shared helper.

Changes:

  • Expand backend-proxy.ts into a shared JSON/text proxy helper with timeout + error handling and consistent base URL resolution.
  • Migrate multiple auth proxy routes (forgot-password, register, reset-password, me, me/change-password, login-check) to use the shared proxy helper.
  • Migrate sandbox/status to the shared helper and add focused tests for auth passthrough, 204 responses, and custom 502 fallbacks.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
web/src/app/api/_utils/backend-proxy.ts Introduces the unified proxy helper layer (base URL, headers/body resolution, timeout + error handling, response building).
web/src/app/api/_utils/backend-proxy.test.ts Adds/updates unit tests covering the new proxy behavior and API.
web/src/app/api/sandbox/status/route.ts Switches sandbox status route to the unified proxy helper.
web/src/app/api/auth/forgot-password/route.ts Switches forgot-password proxy to the unified proxy helper.
web/src/app/api/auth/register/route.ts Switches register proxy to the unified proxy helper.
web/src/app/api/auth/reset-password/route.ts Switches reset-password proxy to the unified proxy helper.
web/src/app/api/auth/me/route.ts Switches auth/me GET/PATCH/DELETE to the unified proxy helper with backend auth.
web/src/app/api/auth/me/change-password/route.ts Switches change-password proxy to the unified proxy helper with backend auth.
web/src/app/api/auth/login-check/route.ts Switches login-check proxy to the unified proxy helper with a custom 502 fallback.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

You can also share your feedback on Copilot code review. Take the survey.

Comment on lines +134 to +146
const contentType =
upstream.headers.get("content-type") || options.responseContentType

if (contentType && upstream.status !== 204 && text.length > 0) {
headers.set("Content-Type", contentType)
}

if (upstream.status === 204 || text.length === 0) {
return new Response(null, {
status: upstream.status,
headers,
})
}
Comment on lines +170 to +177
const detail = error instanceof Error ? error.message : String(error)

return Response.json(
{
detail: isTimeout
? `Upstream API timed out: ${upstreamUrl}`
: `Upstream API unreachable: ${upstreamUrl}`,
error: detail,
@jerry609 jerry609 merged commit 78f99ea into dev Mar 15, 2026
20 checks passed
@jerry609 jerry609 deleted the refactor/pr12-next-proxy-remaining branch March 15, 2026 13:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants