Skip to content

chore(core): clean up core package#128

Merged
halvaradop merged 2 commits intomasterfrom
chore/clean-up
Mar 25, 2026
Merged

chore(core): clean up core package#128
halvaradop merged 2 commits intomasterfrom
chore/clean-up

Conversation

@halvaradop
Copy link
Copy Markdown
Member

@halvaradop halvaradop commented Mar 25, 2026

Description

This pull request performs a cleanup and restructuring of the core package to improve organization, separation of concerns, and maintainability. The changes introduce a clearer modular structure that prepares the codebase for future expansions, including upcoming packages such as database adapters and framework-specific integrations.

The refactor focuses on reorganizing files and folders, isolating responsibilities, and improving overall code clarity without altering existing functionality.

Key Changes

  • Created shared folder for reusable utilities and common logic
  • Created router folder to isolate routing-related logic
  • Separated types into dedicated files for better structure and scalability
  • Exported createJoseInstance for external usage
  • Removed deprecated generateSecure code

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced createJoseInstance as a new public API for JWT token management.
    • Added error handling utilities with createErrorHandler export.
    • Expanded public type exports including AuthConfig, JWTConfig, SessionStrategy, and session configuration types.
    • Added new API re-exports for signIn, signOut, getSession, and createAuthAPI functions.
  • Refactor

    • Reorganized internal module structure to improve code maintainability and separation of concerns.

@vercel
Copy link
Copy Markdown
Contributor

vercel bot commented Mar 25, 2026

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

Project Deployment Actions Updated (UTC)
auth Ready Ready Preview, Comment Mar 25, 2026 3:47pm

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 25, 2026

Warning

Rate limit exceeded

@halvaradop has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 11 minutes and 54 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: defaults

Review profile: CHILL

Plan: Pro

Run ID: 5ae17a92-6373-40ef-8be0-8fbd092c86a7

📥 Commits

Reviewing files that changed from the base of the PR and between 569f244 and e9f6443.

📒 Files selected for processing (48)
  • packages/core/src/@types/config.ts
  • packages/core/src/@types/oauth.ts
  • packages/core/src/@types/session.ts
  • packages/core/src/actions/callback/access-token.ts
  • packages/core/src/actions/callback/callback.ts
  • packages/core/src/actions/callback/userinfo.ts
  • packages/core/src/actions/csrfToken/csrfToken.ts
  • packages/core/src/actions/session/session.ts
  • packages/core/src/actions/signIn/authorization-url.ts
  • packages/core/src/actions/signIn/authorization.ts
  • packages/core/src/actions/signOut/signOut.ts
  • packages/core/src/api/createApi.ts
  • packages/core/src/api/getSession.ts
  • packages/core/src/api/signIn.ts
  • packages/core/src/client/client.ts
  • packages/core/src/cookie.ts
  • packages/core/src/createAuth.ts
  • packages/core/src/index.ts
  • packages/core/src/jose.ts
  • packages/core/src/oauth/index.ts
  • packages/core/src/oauth/notion.ts
  • packages/core/src/oauth/twitch.ts
  • packages/core/src/router/context.ts
  • packages/core/src/router/errorHandler.ts
  • packages/core/src/session/cookie-manager.ts
  • packages/core/src/session/index.ts
  • packages/core/src/session/jose-manager.ts
  • packages/core/src/session/stateless.ts
  • packages/core/src/session/strategy.ts
  • packages/core/src/shared/assert.ts
  • packages/core/src/shared/env.ts
  • packages/core/src/shared/errors.ts
  • packages/core/src/shared/fetch-async.ts
  • packages/core/src/shared/headers.ts
  • packages/core/src/shared/logger.ts
  • packages/core/src/shared/security.ts
  • packages/core/src/shared/utils.ts
  • packages/core/test/actions/callback/access-token.test.ts
  • packages/core/test/actions/callback/callback.test.ts
  • packages/core/test/actions/callback/userinfo.test.ts
  • packages/core/test/actions/session/session.test.ts
  • packages/core/test/actions/signOut/signOut.test.ts
  • packages/core/test/assert.test.ts
  • packages/core/test/context.test.ts
  • packages/core/test/env.test.ts
  • packages/core/test/jose.test.ts
  • packages/core/test/request.test.ts
  • packages/core/test/secure.test.ts
📝 Walkthrough

Walkthrough

This PR reorganizes the TypeScript type system and utility modules by introducing new type-specific modules (@types/config.ts, @types/errors.ts, @types/oauth.ts), creating a shared/ directory structure for utility functions, consolidating type exports in the main index, and updating all internal imports accordingly. It also extracts the session strategy factory and error handler logic into dedicated modules.

Changes

Cohort / File(s) Summary
New Type Definition Modules
packages/core/src/@types/config.ts, packages/core/src/@types/errors.ts, packages/core/src/@types/oauth.ts
Added 249 new lines of structured TypeScript type definitions: AuthConfig<DefaultUser>, cookie strategy types, OAuth provider configuration interfaces, logger types, auth runtime contracts, and OAuth/authentication error code unions.
Type Index Reorganization
packages/core/src/@types/index.ts
Removed 422 lines of previously in-file type definitions (moved to new @types/*.ts modules), now re-exporting from config.ts, errors.ts, oauth.ts, session.ts, utility.ts. Added deprecation marker to JWTStandardClaims.
Utility Function Redistribution
packages/core/src/utils.ts (removed), packages/core/src/shared/utils.ts (added), packages/core/src/shared/security.ts, packages/core/src/shared/logger.ts, packages/core/src/shared/assert.ts
Deleted monolithic utils.ts (182 lines); distributed utilities across specialized shared modules: shared/utils.ts (+106 lines) exports AURA_AUTH_VERSION, equals, getBaseURL, isSecureConnection, formatZodError, extractPath, getErrorName, validateRedirectTo, patternToRegex, timingSafeEqual. Removed generateSecure from shared/security.ts, added JWT mode type guards to shared/assert.ts, added createStructuredData to shared/logger.ts.
Router & API Handler Additions
packages/core/src/router/errorHandler.ts (new), packages/core/src/api/index.ts, packages/core/src/index.ts
Added new createErrorHandler(logger?) factory (+72 lines) implementing error classification and JSON response mapping. Exported new API functions: createAuthAPI, signIn, signOut, getSession via api/index.ts. Main entry point now exports createJoseInstance and JWT/session config types.
Session Strategy & Manager Refactoring
packages/core/src/session/strategy.ts (new), packages/core/src/session/index.ts, packages/core/src/session/jose-manager.ts
Extracted createSessionStrategy factory to dedicated strategy.ts module (+24 lines), now delegating from session/index.ts. Moved JWTManager type definition from jose-manager.ts to type definitions.
Core Auth Configuration
packages/core/src/createAuth.ts, packages/core/src/router/context.ts
Threaded DefaultUser generic through createAuthInstance/createAuth signatures. Replaced useSecureCookies() logic with direct isSecureConnection(ctx.request, trustedProxyHeaders) check. Updated dependency imports for env, logger, and session creation.
OAuth & Session Module Updates
packages/core/src/oauth/index.ts, packages/core/src/oauth/*.ts, packages/core/src/session/*.ts
Added new createBasicAuthHeader(username, password) helper in oauth/index.ts. Updated all OAuth and session modules to import from @/shared/* paths instead of top-level modules.
Action Endpoints Import Updates
packages/core/src/actions/callback/*.ts, packages/core/src/actions/csrfToken/*.ts, packages/core/src/actions/session/*.ts, packages/core/src/actions/signIn/*.ts, packages/core/src/actions/signOut/*.ts, packages/core/src/api/*.ts
Updated imports across all endpoint handlers to reference @/shared/errors.ts, @/shared/headers.ts, @/shared/security.ts, @/shared/utils.ts, @/shared/env.ts instead of top-level or old module locations. No endpoint logic or control flow changed.
Cookie & Client Modules
packages/core/src/cookie.ts, packages/core/src/client/client.ts
Updated import sources for env and error types to use @/shared/* paths. No exported interface or runtime behavior changes.
Test File Updates
packages/core/test/**/*.test.ts
Updated test import paths across callback, session, signOut, assert, context, env, jose, request, and secure test files to reference @/shared/* modules and new function sources. Removed test/utils.test.ts (64 lines of test cases for removed utility functions).
Session Type Additions
packages/core/src/@types/session.ts
Added new API option types: SignInOptions, SignOutOptions, GetSessionAPIOptions, SignOutAPIOptions, SignInAPIOptions, SignInReturn conditional, SessionResponse discriminated union; reordered and added JWTManager<DefaultUser> type definition.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

Possibly related PRs

Suggested labels

refactor

Poem

🐰 Whiskers twitch with glee—
Types now dance in new abodes,
Utils scattered free,
Shared helpers find their codes,
Refactor's melody!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'chore(core): clean up core package' accurately describes the main change—a comprehensive refactoring that reorganizes the core package's module structure by creating a 'shared' namespace for utility functions and moving scattered utilities into organized submodules.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/clean-up

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: 3

🧹 Nitpick comments (9)
packages/core/src/@types/errors.ts (1)

27-32: Suggested refactor for TokenRevocationError is incorrect—it conflates different OAuth specs.

The proposed fix incorrectly references OAuthAccessTokenErrorResponse (RFC6749 access token errors) for RFC7009 token revocation errors, which have distinct error codes. Additionally, TokenRevocationError is currently unused in the codebase (only appears in the ErrorType union definition).

If RFC7009 compliance is needed, create a dedicated OAuthTokenRevocationErrorResponse Zod schema following RFC7009 Section 2.2.1, rather than reusing the access token error spec. For now, since this type is unused, consider whether it should remain as a placeholder or be removed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/`@types/errors.ts around lines 27 - 32,
TokenRevocationError currently aliases OAuthError<"invalid_session_token"> and
the suggested refactor in the comment wrongly conflates RFC7009 revocation
errors with RFC6749 access token errors; either implement a dedicated RFC7009
schema or remove the unused placeholder: create a new
OAuthTokenRevocationErrorResponse Zod schema matching RFC7009 Section 2.2.1 and
change TokenRevocationError to reference that schema (or delete
TokenRevocationError and remove it from the ErrorType union if you choose to
drop the unused placeholder), ensuring you update any references in ErrorType
and keep AuthorizationError, AccessTokenError, and OAuthError untouched.
packages/core/src/router/context.ts (1)

37-37: Consider fixing the type at the source instead of casting.

The cast as InternalContext<DefaultUser>["sessionStrategy"] is needed because createSessionStrategy returns SessionStrategy without preserving the generic type parameter. While this cast is safe at runtime, it would be cleaner to have createSessionStrategy explicitly return SessionStrategy<DefaultUser> to avoid the need for this assertion.

Suggested change in `packages/core/src/session/index.ts`
 export const createSessionStrategy = <DefaultUser extends User = User>({
     config,
     jose,
     cookies,
     logger,
-}: CreateSessionStrategyOptions<DefaultUser>): SessionStrategy => {
+}: CreateSessionStrategyOptions<DefaultUser>): SessionStrategy<DefaultUser> => {

This would allow removing the cast here:

     ctx.sessionStrategy = createSessionStrategy({
         cookies: () => ctx.cookies,
         jose,
         config: config?.session,
         logger: ctx.logger,
-    }) as InternalContext<DefaultUser>["sessionStrategy"]
+    })
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/router/context.ts` at line 37, The cast is compensating for
createSessionStrategy losing its generic; update createSessionStrategy's
signature to return SessionStrategy<TUser> (preserve the generic) and ensure its
implementation and exports use that generic type parameter (so callers can
supply DefaultUser). Update any internal usages to pass the appropriate type
parameter, then remove the `as InternalContext<DefaultUser>["sessionStrategy"]`
assertion where `sessionStrategy` is assigned; reference symbols:
createSessionStrategy, SessionStrategy, DefaultUser, InternalContext,
sessionStrategy.
packages/core/src/security.ts (2)

43-55: Unused variable token on line 45.

The token variable created on line 45 is never used when csrfCookie is provided and successfully verified (lines 46-49 return early). This is dead code in the happy path.

♻️ Proposed fix to avoid unnecessary computation
 export const createCSRF = async (jose: AuthRuntimeConfig["jose"], csrfCookie?: string) => {
     try {
-        const token = createSecretValue(32)
         if (csrfCookie) {
             await jose.verifyJWS(csrfCookie)
             return csrfCookie
         }
+        const token = createSecretValue(32)
         return jose.signJWS({ token })
     } catch {
         const token = createSecretValue(32)
         return jose.signJWS({ token })
     }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/security.ts` around lines 43 - 55, The createCSRF function
currently always creates a token via createSecretValue(32) even when csrfCookie
is provided and verified, making the token unused; update createCSRF so it first
checks if csrfCookie exists and successfully calls jose.verifyJWS(csrfCookie)
and returns csrfCookie without allocating a token, and only call
createSecretValue(32) (and then jose.signJWS({ token })) in the code paths where
you actually need to sign a new token (the else branch and the catch block);
reference createCSRF, token, jose.verifyJWS, and jose.signJWS when making the
change.

73-78: Consider removing redundant length check.

The equals(cookiePayload.token.length, headerPayload.token.length) check on line 73 is redundant. The timingSafeEqual implementation already handles different-length strings securely by iterating over the maximum length and checking bufferA.length === bufferB.length at the end.

While not a security issue (integer comparison doesn't leak timing), removing it would simplify the code.

♻️ Proposed simplification
-        if (!equals(cookiePayload.token.length, headerPayload.token.length)) {
-            throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.")
-        }
         if (!timingSafeEqual(cookiePayload.token, headerPayload.token)) {
             throw new AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF tokens do not match.")
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/security.ts` around lines 73 - 78, Remove the redundant
length comparison using equals(cookiePayload.token.length,
headerPayload.token.length) and rely solely on
timingSafeEqual(cookiePayload.token, headerPayload.token) to validate CSRF
tokens; keep the existing AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF
tokens do not match.") thrown when timingSafeEqual returns false, and ensure
only the timingSafeEqual call (and its error throw) remains in the token
comparison logic.
packages/core/src/createAuth.ts (1)

9-9: Type parameter not propagated to AuthConfig.

The createInternalConfig function accepts AuthConfig instead of AuthConfig<DefaultUser>, which loses the custom user type information. This should use the generic parameter for type consistency.

♻️ Proposed fix
-const createInternalConfig = <DefaultUser extends User = User>(authConfig?: AuthConfig): RouterConfig => {
+const createInternalConfig = <DefaultUser extends User = User>(authConfig?: AuthConfig<DefaultUser>): RouterConfig => {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/createAuth.ts` at line 9, The function createInternalConfig
uses a generic DefaultUser but accepts AuthConfig without the generic, losing
the custom user type; update the parameter type to AuthConfig<DefaultUser> in
the createInternalConfig signature so the DefaultUser generic is propagated, and
verify any internal uses of authConfig (within createInternalConfig) respect
DefaultUser and return RouterConfig with the generic applied.
packages/core/src/router/errorHandler.ts (1)

25-31: Minor: Redundant property shorthand.

Line 28 uses message: message which can be simplified to message.

Proposed fix
             return Response.json(
                 {
                     type,
-                    message: message,
+                    message,
                 },
                 { status: 400 }
             )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/router/errorHandler.ts` around lines 25 - 31, In the
Response.json call inside the error handler (the return Response.json(...)
block), simplify the redundant object property by using the shorthand key for
message instead of message: message; update the returned object to { type,
message } to match the existing shorthand used for type.
packages/core/src/@types/config.ts (1)

228-232: Generic type parameter lost in alias.

AuthRuntimeConfig is defined as RouterGlobalContext without a type parameter, defaulting to User. If callers need to preserve a custom DefaultUser type, they'll need to use RouterGlobalContext<CustomUser> directly. Consider whether this alias should also accept a generic.

Proposed fix if generic preservation is needed
 /**
  * Internal runtime configuration used within Aura Auth after initialization.
  * All optional fields from AuthConfig are resolved to their default values.
  */
-export type AuthRuntimeConfig = RouterGlobalContext
+export type AuthRuntimeConfig<DefaultUser extends User = User> = RouterGlobalContext<DefaultUser>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/`@types/config.ts around lines 228 - 232, AuthRuntimeConfig
currently aliases RouterGlobalContext without a generic, which forces the
DefaultUser type and prevents preserving custom user types; update the alias to
accept a generic type parameter (e.g., AuthRuntimeConfig<DefaultUser> or
similar) and forward it to RouterGlobalContext so callers can use
AuthRuntimeConfig<CustomUser> to retain their user type; adjust any
usages/imports of AuthRuntimeConfig to pass the generic where needed and keep
the existing default type to preserve backward compatibility.
packages/core/src/lib/utils.ts (2)

96-118: ReDoS risk is mitigated but consider additional safeguards.

Static analysis flagged the dynamic regex construction (Line 114). The current implementation has good mitigations:

  • Length limit (2048 chars)
  • Strict input validation via the format regex (Line 101)
  • Special character escaping (Line 110)
  • Anchored regex (^...$)

However, for defense-in-depth, consider adding a timeout or using a dedicated library for URL matching if this function processes untrusted input at scale.

If you want to eliminate the dynamic regex entirely, consider using URL parsing:

// Alternative: Parse and compare URL components directly
const matchOrigin = (pattern: string, origin: string): boolean => {
    // Parse both and compare protocol, host parts
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/lib/utils.ts` around lines 96 - 118, patternToRegex
currently builds a dynamic RegExp from untrusted patterns which, while
mitigated, still poses ReDoS risk; replace the dynamic-regex approach by parsing
and comparing URL components instead: update patternToRegex (or add a new
matchOrigin function) to use URL parsing (new URL) to validate the input pattern
and the target origin, then compare protocol, handle host wildcards by splitting
and matching labels (supporting only *.prefix at start), and compare port
explicitly — this removes the need to construct a runtime regex and keeps the
same validations (length, wildcard placement, escaped characters) while avoiding
dynamic regex creation; alternatively, if keeping regex, add an explicit
safe-guard that rejects any pattern containing nested quantifiers or other
catastrophic constructs before building the RegExp.

70-78: Specify minimum Node.js version or add btoa() fallback if supporting older environments.

btoa() is available in Node.js 16+, which the CI tests against (Node.js 24.x). However, since no minimum Node.js version is specified in package.json, users could theoretically install this package on older versions or unsupported runtimes. Either:

  • Add "engines": { "node": ">=16" } to explicitly document the minimum version, or
  • Use Buffer.from(credentials, 'utf-8').toString('base64') as a runtime-agnostic fallback if broader compatibility is needed.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/core/src/lib/utils.ts` around lines 70 - 78, The
createBasicAuthHeader function uses btoa(credentials), which may not exist in
older Node runtimes; update the implementation to use a runtime-agnostic base64
encoder (e.g., prefer Buffer.from(credentials, 'utf-8').toString('base64') with
a btoa fallback) or alternatively document a minimum Node version by adding an
"engines": { "node": ">=16" } entry in package.json; locate
createBasicAuthHeader in packages/core/src/lib/utils.ts and replace the btoa
usage with the Buffer-based encoding (or add the engines field) to ensure
predictable behavior across environments.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/core/src/`@types/oauth.ts:
- Around line 47-51: The deprecation comment for the top-level responseType is
inconsistent (references authorize.params.response_type) — update the comment to
point to the actual camelCase property authorize.params.responseType; change the
deprecated JSDoc to "use `authorize.params.responseType` instead of
`responseType`" so it matches the existing params definition and avoid
snake_case reference. Ensure the unique symbols mentioned are responseType
(top-level) and authorize.params.responseType (replacement).
- Around line 23-41: The TypeScript interface declares authorize.url,
accessToken.url and userInfo.url as string but the Zod schemas are inconsistent
(authorize uses string().url() while accessToken and userInfo use url() which
accepts URL objects); fix by making the Zod validators consistent with the
TypeScript types: change the accessToken.url and userInfo.url validators to use
string().url() (same form as authorize.url) so all three endpoints validate as
strings, or alternatively update the interface to url: string | URL for
accessToken and userInfo if you prefer accepting URL objects—apply the chosen
change to the validators/types referencing authorize, accessToken, and userInfo
and ensure related param types (AuthorizeParams, ResponseType) remain unchanged.

In `@packages/core/src/router/errorHandler.ts`:
- Around line 49-64: The current security error handling uses a misleading log
key "INVALID_OAUTH_CONFIGURATION"; update the logger call in the
isAuthSecurityError branch to use a generic/auth category (e.g.,
"AUTH_SECURITY_ERROR") instead, leaving the structuredData payload (error: code,
error_description: message) intact and still returning Response.json with the
same { type, code, message } and status 400; adjust the logger invocation where
logger?.log is called so it reflects AUTH_SECURITY_ERROR rather than
INVALID_OAUTH_CONFIGURATION.

---

Nitpick comments:
In `@packages/core/src/`@types/config.ts:
- Around line 228-232: AuthRuntimeConfig currently aliases RouterGlobalContext
without a generic, which forces the DefaultUser type and prevents preserving
custom user types; update the alias to accept a generic type parameter (e.g.,
AuthRuntimeConfig<DefaultUser> or similar) and forward it to RouterGlobalContext
so callers can use AuthRuntimeConfig<CustomUser> to retain their user type;
adjust any usages/imports of AuthRuntimeConfig to pass the generic where needed
and keep the existing default type to preserve backward compatibility.

In `@packages/core/src/`@types/errors.ts:
- Around line 27-32: TokenRevocationError currently aliases
OAuthError<"invalid_session_token"> and the suggested refactor in the comment
wrongly conflates RFC7009 revocation errors with RFC6749 access token errors;
either implement a dedicated RFC7009 schema or remove the unused placeholder:
create a new OAuthTokenRevocationErrorResponse Zod schema matching RFC7009
Section 2.2.1 and change TokenRevocationError to reference that schema (or
delete TokenRevocationError and remove it from the ErrorType union if you choose
to drop the unused placeholder), ensuring you update any references in ErrorType
and keep AuthorizationError, AccessTokenError, and OAuthError untouched.

In `@packages/core/src/createAuth.ts`:
- Line 9: The function createInternalConfig uses a generic DefaultUser but
accepts AuthConfig without the generic, losing the custom user type; update the
parameter type to AuthConfig<DefaultUser> in the createInternalConfig signature
so the DefaultUser generic is propagated, and verify any internal uses of
authConfig (within createInternalConfig) respect DefaultUser and return
RouterConfig with the generic applied.

In `@packages/core/src/lib/utils.ts`:
- Around line 96-118: patternToRegex currently builds a dynamic RegExp from
untrusted patterns which, while mitigated, still poses ReDoS risk; replace the
dynamic-regex approach by parsing and comparing URL components instead: update
patternToRegex (or add a new matchOrigin function) to use URL parsing (new URL)
to validate the input pattern and the target origin, then compare protocol,
handle host wildcards by splitting and matching labels (supporting only *.prefix
at start), and compare port explicitly — this removes the need to construct a
runtime regex and keeps the same validations (length, wildcard placement,
escaped characters) while avoiding dynamic regex creation; alternatively, if
keeping regex, add an explicit safe-guard that rejects any pattern containing
nested quantifiers or other catastrophic constructs before building the RegExp.
- Around line 70-78: The createBasicAuthHeader function uses btoa(credentials),
which may not exist in older Node runtimes; update the implementation to use a
runtime-agnostic base64 encoder (e.g., prefer Buffer.from(credentials,
'utf-8').toString('base64') with a btoa fallback) or alternatively document a
minimum Node version by adding an "engines": { "node": ">=16" } entry in
package.json; locate createBasicAuthHeader in packages/core/src/lib/utils.ts and
replace the btoa usage with the Buffer-based encoding (or add the engines field)
to ensure predictable behavior across environments.

In `@packages/core/src/router/context.ts`:
- Line 37: The cast is compensating for createSessionStrategy losing its
generic; update createSessionStrategy's signature to return
SessionStrategy<TUser> (preserve the generic) and ensure its implementation and
exports use that generic type parameter (so callers can supply DefaultUser).
Update any internal usages to pass the appropriate type parameter, then remove
the `as InternalContext<DefaultUser>["sessionStrategy"]` assertion where
`sessionStrategy` is assigned; reference symbols: createSessionStrategy,
SessionStrategy, DefaultUser, InternalContext, sessionStrategy.

In `@packages/core/src/router/errorHandler.ts`:
- Around line 25-31: In the Response.json call inside the error handler (the
return Response.json(...) block), simplify the redundant object property by
using the shorthand key for message instead of message: message; update the
returned object to { type, message } to match the existing shorthand used for
type.

In `@packages/core/src/security.ts`:
- Around line 43-55: The createCSRF function currently always creates a token
via createSecretValue(32) even when csrfCookie is provided and verified, making
the token unused; update createCSRF so it first checks if csrfCookie exists and
successfully calls jose.verifyJWS(csrfCookie) and returns csrfCookie without
allocating a token, and only call createSecretValue(32) (and then jose.signJWS({
token })) in the code paths where you actually need to sign a new token (the
else branch and the catch block); reference createCSRF, token, jose.verifyJWS,
and jose.signJWS when making the change.
- Around line 73-78: Remove the redundant length comparison using
equals(cookiePayload.token.length, headerPayload.token.length) and rely solely
on timingSafeEqual(cookiePayload.token, headerPayload.token) to validate CSRF
tokens; keep the existing AuthSecurityError("CSRF_TOKEN_INVALID", "The CSRF
tokens do not match.") thrown when timingSafeEqual returns false, and ensure
only the timingSafeEqual call (and its error throw) remains in the token
comparison logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2b75de73-2b50-4c56-b7b4-252617d53a26

📥 Commits

Reviewing files that changed from the base of the PR and between d8b1ed3 and 3748273.

📒 Files selected for processing (52)
  • packages/core/src/@types/config.ts
  • packages/core/src/@types/errors.ts
  • packages/core/src/@types/index.ts
  • packages/core/src/@types/oauth.ts
  • packages/core/src/@types/session.ts
  • packages/core/src/actions/callback/access-token.ts
  • packages/core/src/actions/callback/callback.ts
  • packages/core/src/actions/callback/userinfo.ts
  • packages/core/src/actions/csrfToken/csrfToken.ts
  • packages/core/src/actions/session/session.ts
  • packages/core/src/actions/signIn/authorization-url.ts
  • packages/core/src/actions/signIn/authorization.ts
  • packages/core/src/actions/signOut/signOut.ts
  • packages/core/src/api/createApi.ts
  • packages/core/src/api/getSession.ts
  • packages/core/src/api/index.ts
  • packages/core/src/api/signIn.ts
  • packages/core/src/client/client.ts
  • packages/core/src/cookie.ts
  • packages/core/src/createAuth.ts
  • packages/core/src/index.ts
  • packages/core/src/jose.ts
  • packages/core/src/lib/assert.ts
  • packages/core/src/lib/errors.ts
  • packages/core/src/lib/fetch-async.ts
  • packages/core/src/lib/headers.ts
  • packages/core/src/lib/logger.ts
  • packages/core/src/lib/utils.ts
  • packages/core/src/oauth/gitlab.ts
  • packages/core/src/oauth/index.ts
  • packages/core/src/oauth/notion.ts
  • packages/core/src/router/context.ts
  • packages/core/src/router/errorHandler.ts
  • packages/core/src/schemas.ts
  • packages/core/src/security.ts
  • packages/core/src/session/index.ts
  • packages/core/src/session/manager/cookie.ts
  • packages/core/src/session/manager/jose.ts
  • packages/core/src/session/strategies/stateless.ts
  • packages/core/src/utils.ts
  • packages/core/test/actions/callback/access-token.test.ts
  • packages/core/test/actions/callback/callback.test.ts
  • packages/core/test/actions/callback/userinfo.test.ts
  • packages/core/test/actions/session/session.test.ts
  • packages/core/test/actions/signOut/signOut.test.ts
  • packages/core/test/assert.test.ts
  • packages/core/test/context.test.ts
  • packages/core/test/env.test.ts
  • packages/core/test/jose.test.ts
  • packages/core/test/request.test.ts
  • packages/core/test/secure.test.ts
  • packages/core/test/utils.test.ts
💤 Files with no reviewable changes (2)
  • packages/core/test/utils.test.ts
  • packages/core/src/utils.ts

@halvaradop halvaradop merged commit e5be5ea into master Mar 25, 2026
6 checks passed
@halvaradop halvaradop deleted the chore/clean-up branch March 25, 2026 15:49
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