Skip to content

refactor(core): align redirect options and response values across APIs#174

Merged
halvaradop merged 5 commits into
masterfrom
refactor/standardize-redirect-options
May 31, 2026
Merged

refactor(core): align redirect options and response values across APIs#174
halvaradop merged 5 commits into
masterfrom
refactor/standardize-redirect-options

Conversation

@halvaradop
Copy link
Copy Markdown
Member

@halvaradop halvaradop commented May 29, 2026

Description

New features are coming soon....

- redirect: boolean
+ redirect: "auto" | "manual"

Summary by CodeRabbit

  • New Features
    • Added redirect and redirectTo options for sign-in and session update endpoints to control post-authentication redirect behavior
    • Implemented server-side redirects via Location headers
    • Enhanced response types to explicitly distinguish redirect vs. non-redirect scenarios

Review Change Stack

Summary by CodeRabbit

  • Refactor
    • Improved authentication redirect behavior: endpoints now include an explicit redirect flag and consistent redirectURL handling so responses indicate when a server-side redirect occurred.
    • Users can disable automatic redirects and still receive a preserved redirectURL when desired (e.g., sign-in, sign-out, session updates).
  • Tests
    • Expanded coverage to validate redirect scenarios and exact response shapes across success/error cases.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 29, 2026

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

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
auth Skipped Skipped May 31, 2026 3:00pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 29, 2026

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b88652c3-18c6-4a06-ac05-18965aff069d

📥 Commits

Reviewing files that changed from the base of the PR and between 71b04d3 and 48615fb.

📒 Files selected for processing (5)
  • packages/core/src/@types/errors.ts
  • packages/core/src/api/signOut.ts
  • packages/core/src/api/updateSession.ts
  • packages/core/test/actions/updateSession/updateSession.test.ts
  • packages/core/test/api/updateSession.test.ts
💤 Files with no reviewable changes (1)
  • packages/core/src/api/signOut.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/core/test/api/updateSession.test.ts

📝 Walkthrough

Walkthrough

Centralizes redirect options into RedirectOptionsSchema, expands APIReturn types to include explicit redirect and nullable redirectURL, wires redirect/redirectTo from action endpoints into API calls, implements conditional Location header server redirects in credentials/signOut/updateSession, and updates tests to assert the new shapes and statuses.

Changes

Redirect handling refactor

Layer / File(s) Summary
Schemas & public types
packages/core/src/schemas.ts, packages/core/src/@types/api.ts
Adds RedirectOptionsSchema and CredentialsPayloadSchema; expands SignInCredentialsAPIReturn, SignOutAPIReturn, and UpdateSessionAPIReturn to include explicit redirect: boolean and `redirectURL: string
Action endpoint wiring and schemas
packages/core/src/actions/signIn/signIn.ts, packages/core/src/actions/signInCredentials/signInCredentials.ts, packages/core/src/actions/signOut/signOut.ts, packages/core/src/actions/updateSession/updateSession.ts
Replaces inline Zod schemas with shared schemas and forwards redirect/redirectTo (and request/headers where applicable) from action handlers into API calls.
API implementations
packages/core/src/api/credentials.ts, packages/core/src/api/signOut.ts, packages/core/src/api/updateSession.ts
APIs default redirect to true, compute/normalize redirect targets, conditionally set Location header for server-side redirects, return updated redirect/redirectURL shapes (success and error paths), and use 302 vs 200/202 appropriately.
Test updates
packages/core/test/* (actions & api)
Tests updated to assert redirect boolean and redirectURL values, verify Location header on server redirects, and strengthen several response assertions to exact matches.
Presets & EOF formatting
packages/core/test/presets.ts, packages/*/package.json
Makes OAuth authorize callback use credentials-derived fields and fixes end-of-file formatting in several package.json files.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

refactor, enhancement

Poem

🐰 I hopped through schemas, types, and tests,
I nudged redirects to their proper nests,
Location only when server says go,
Null or string — the responses now know.
Tests clap their paws: true or false, all blessed.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: aligning redirect options and response values across multiple APIs.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/standardize-redirect-options

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a 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

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/api/updateSession.ts`:
- Around line 43-60: The branch returning { headers: newHeaders, session,
success: isSuccess, ... } must include an error field when refreshSession()
yields session === null so it complies with
UpdateSessionAPIReturn/AuthActionAPIReturn; update the return object (and the
inner toResponse payload) to set error to a descriptive string or error object
whenever isSuccess is false (e.g., "Session refresh failed" or include
underlying reason), and ensure the Response.status remains 401 for failures;
look for refreshSession(), UpdateSessionAPIReturn, toResponse and ensure both
the top-level return value and the Response.json body include the error property
on non-throwing failures.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b1d75242-6238-47c9-b9fd-dc37bce75c1b

📥 Commits

Reviewing files that changed from the base of the PR and between dfb5615 and 056cdbf.

📒 Files selected for processing (7)
  • packages/core/src/@types/api.ts
  • packages/core/src/actions/signIn/signIn.ts
  • packages/core/src/actions/updateSession/updateSession.ts
  • packages/core/src/api/updateSession.ts
  • packages/core/src/schemas.ts
  • packages/core/test/actions/updateSession/updateSession.test.ts
  • packages/core/test/api/updateSession.test.ts

Comment thread packages/core/src/api/updateSession.ts
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a 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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/core/test/api/signInCredentials.test.ts (1)

56-84: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

This fixture is exercising missing BASE_URL, not the invalid-authorize branch.

Because BASE_URL is still unset here, the assertion now locks in INVALID_OAUTH_CONFIGURATION, which duplicates the dedicated URL-configuration test below instead of verifying the "missing required fields" path. Stub a valid base URL in this case so it actually covers the malformed authorize return.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/test/api/signInCredentials.test.ts` around lines 56 - 84, The
test "invalid authorize by missing required fields" is failing because BASE_URL
is unset and triggers INVALID_OAUTH_CONFIGURATION; to fix it, stub a valid base
URL before creating the auth instance so the test exercises the malformed
authorize return path: set process.env.BASE_URL (or pass a baseUrl option if
createAuth supports it) prior to calling createAuth(...) and then call
api.signInCredentials(...) as-is to assert the missing-required-fields behavior
from the authorize function; ensure changes reference the test name, createAuth,
the credentials.authorize stub, and api.signInCredentials.
🧹 Nitpick comments (2)
packages/core/test/api/signOut.test.ts (1)

96-118: ⚡ Quick win

Also assert that redirect: false clears the Location header.

This branch is specifically about suppressing server-side redirects, so the API test should lock that down as well instead of only checking the JSON shape.

Suggested fix
         const out = await api.signOut({
             headers: {
                 Cookie: `aura-auth.session_token=${sessionToken}; aura-auth.csrf_token=${csrfToken}`,
             },
             redirect: false,
             redirectTo: "/dashboard",
         })
+        expect(out.headers.get("Location")).toBeNull()
         expect(out).toEqual({
             success: true,
             redirect: false,
             redirectURL: "/dashboard",
             headers: expect.any(Headers),
             toResponse: expect.any(Function),
         })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/test/api/signOut.test.ts` around lines 96 - 118, The test
"signOut with redirect: false and redirectTo" currently only asserts the JSON
shape; add an assertion that the response headers do not include a Location
header when redirect is false. After calling api.signOut in the test, inspect
the returned out.headers (the Headers object) and assert that
out.headers.get("Location") is null (or strictly falsy) to ensure server-side
redirects are suppressed; update the test around the api.signOut invocation in
signOut.test.ts accordingly.
packages/core/test/api/signInCredentials.test.ts (1)

157-173: ⚡ Quick win

The redirect: false path is not being tested here.

This case never passes redirect: false, so it currently re-tests the default redirect-enabled behavior and leaves the non-redirect API contract uncovered.

Suggested fix
     test("signIn with redirect: false and valid redirectTo", async () => {
         vi.stubEnv("BASE_URL", "https://example.com")

         const signIn = await api.signInCredentials({
             payload: {
                 username: "johndoe",
                 password: "1234567890",
             },
+            redirect: false,
             redirectTo: "https://example.com/dashboard",
         })
+        expect(signIn.headers.get("Location")).toBeNull()
         expect(signIn).toEqual({
             success: true,
-            redirect: true,
-            redirectURL: null,
+            redirect: false,
+            redirectURL: "/dashboard",
             headers: expect.any(Headers),
             toResponse: expect.any(Function),
         })
     })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/core/test/api/signInCredentials.test.ts` around lines 157 - 173, The
test currently calls api.signInCredentials without passing redirect: false so it
exercises the default redirect-enabled path; update or add the test for
api.signInCredentials (the "signIn with redirect: false and valid redirectTo"
case) to pass redirect: false in the call and assert the non-redirect contract:
expect success true, redirect false, redirectURL to equal the provided
redirectTo (or appropriate non-null value), headers to be a Headers instance,
and toResponse to be a function; keep the BASE_URL stub (vi.stubEnv("BASE_URL",
"https://example.com")) as needed and mirror existing assertions but with
redirect:false and the expected redirectURL value.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/core/src/api/signOut.ts`:
- Around line 59-66: The error response in toResponse (inside signOut.ts) has a
typo and inconsistent structure; change the JSON body to match the success-path
shape by removing the headers field, rename redirectsURL to redirectURL, and
return a Response with an explicit non-200 status (e.g., status: 500) and any
HTTP headers passed via the Response init headers option rather than inside the
JSON body; update the toResponse implementation to return Response.json({
success: false, redirect: false, redirectURL: null }, { status: 500, headers })
so clients receive the correct contract.

---

Outside diff comments:
In `@packages/core/test/api/signInCredentials.test.ts`:
- Around line 56-84: The test "invalid authorize by missing required fields" is
failing because BASE_URL is unset and triggers INVALID_OAUTH_CONFIGURATION; to
fix it, stub a valid base URL before creating the auth instance so the test
exercises the malformed authorize return path: set process.env.BASE_URL (or pass
a baseUrl option if createAuth supports it) prior to calling createAuth(...) and
then call api.signInCredentials(...) as-is to assert the missing-required-fields
behavior from the authorize function; ensure changes reference the test name,
createAuth, the credentials.authorize stub, and api.signInCredentials.

---

Nitpick comments:
In `@packages/core/test/api/signInCredentials.test.ts`:
- Around line 157-173: The test currently calls api.signInCredentials without
passing redirect: false so it exercises the default redirect-enabled path;
update or add the test for api.signInCredentials (the "signIn with redirect:
false and valid redirectTo" case) to pass redirect: false in the call and assert
the non-redirect contract: expect success true, redirect false, redirectURL to
equal the provided redirectTo (or appropriate non-null value), headers to be a
Headers instance, and toResponse to be a function; keep the BASE_URL stub
(vi.stubEnv("BASE_URL", "https://example.com")) as needed and mirror existing
assertions but with redirect:false and the expected redirectURL value.

In `@packages/core/test/api/signOut.test.ts`:
- Around line 96-118: The test "signOut with redirect: false and redirectTo"
currently only asserts the JSON shape; add an assertion that the response
headers do not include a Location header when redirect is false. After calling
api.signOut in the test, inspect the returned out.headers (the Headers object)
and assert that out.headers.get("Location") is null (or strictly falsy) to
ensure server-side redirects are suppressed; update the test around the
api.signOut invocation in signOut.test.ts accordingly.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1a0bea56-07d5-4452-a8ee-c41eb56e29b5

📥 Commits

Reviewing files that changed from the base of the PR and between 056cdbf and 71b04d3.

📒 Files selected for processing (17)
  • packages/core/src/@types/api.ts
  • packages/core/src/actions/signInCredentials/signInCredentials.ts
  • packages/core/src/actions/signOut/signOut.ts
  • packages/core/src/api/credentials.ts
  • packages/core/src/api/signOut.ts
  • packages/core/src/api/updateSession.ts
  • packages/core/src/schemas.ts
  • packages/core/test/actions/signInCredentials/signInCredentials.test.ts
  • packages/core/test/actions/signOut/signOut.test.ts
  • packages/core/test/api/signInCredentials.test.ts
  • packages/core/test/api/signOut.test.ts
  • packages/core/test/api/updateSession.test.ts
  • packages/core/test/presets.ts
  • packages/elysia/package.json
  • packages/express/package.json
  • packages/hono/package.json
  • packages/integration/package.json
✅ Files skipped from review due to trivial changes (4)
  • packages/hono/package.json
  • packages/integration/package.json
  • packages/express/package.json
  • packages/elysia/package.json
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/core/src/api/updateSession.ts
  • packages/core/test/api/updateSession.test.ts

Comment thread packages/core/src/api/signOut.ts
@halvaradop halvaradop merged commit f49c924 into master May 31, 2026
7 checks passed
@halvaradop halvaradop deleted the refactor/standardize-redirect-options branch May 31, 2026 15:17
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.

1 participant