fix: NextJS security upgrade. - #951
Open
jonathanp-okta wants to merge 5 commits into
Open
Conversation
jonathanp-okta
had a problem deploying
to
preview
August 28, 2026 19:53 — with
GitHub Actions
Failure
jonathanp-okta
had a problem deploying
to
preview
August 28, 2026 20:42 — with
GitHub Actions
Failure
jonathanp-okta
had a problem deploying
to
preview
August 28, 2026 21:16 — with
GitHub Actions
Failure
jonathanp-okta
had a problem deploying
to
preview
August 29, 2026 00:53 — with
GitHub Actions
Failure
jonathanp-okta
had a problem deploying
to
preview
August 29, 2026 00:57 — with
GitHub Actions
Failure
|
Preview URL https://next-jwt-ouc57bwdm-okta.vercel.app |
|
Preview URL https://next-jwt-ey912uwk2-okta.vercel.app |
jonathanp-okta
force-pushed
the
fix/next-security-upgrade
branch
from
August 29, 2026 01:45
c97abfe to
ce3df13
Compare
|
Preview URL https://next-jwt-3u1zkjzwp-okta.vercel.app |
|
Preview URL https://next-jwt-5utyyy7ri-okta.vercel.app |
jonathanp-okta
marked this pull request as ready for review
September 1, 2026 06:20
jcmartinezdev
requested changes
Sep 2, 2026
| @@ -0,0 +1,104 @@ | |||
| #!/usr/bin/env node | |||
Contributor
There was a problem hiding this comment.
Why do we need this file? jwt doesn't use jfrog.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
✏️ Changes
This upgrades
nextfrom14.2.35to16.3.3(witheslint-config-nextand@next/mdx/@next/third-partiesbumped in lockstep) to patch . The branch history shows the move was staged through15.5.24first (e3655c7) before continuing to16.3.3(48432f8, d9bccc9) — landing on the current major in one PR rather than opening a second migration shortly after. React stays on18.3.1throughout:16.3.3accepts^18.2.0 || ^19.0.0as a peer, so this is not a React 19 migration, and none of the direct dependencies (react-select,react-aria-components,react-markdown) pinreact@^18only — a future React 19 move stays unblocked.Next 16 defaults to Turbopack, which broke
@next/mdx: its loader registers as a plain top-level webpack rule with no App Router layer, so.mdxmodules picked upnode_modules' JSX runtime instead of Next's precompiled one and crashed in dev withReactCurrentDispatcher of undefined.dev/buildnow pass--webpackexplicitly, andnext.config.mjsaliasesreact/jsx-runtime/react/jsx-dev-runtimeto Next's compiled copies for the.mdxrule specifically (see the comment innext.config.mjs).next lintwas removed in Next 16.0, solintnow runseslint .directly. Bumpingeslintfrom^8to^9in the same PR meant ESLint's flat-config default would have silently ignored the legacy.eslintrc.json—eslint.config.mjsreplaces it as a direct re-export ofeslint-config-next/core-web-vitals(confirmed to ship real flat-config arrays in v16, noFlatCompatshim needed), with two App Router-specific rule overrides carried over with their rationale in a comment.next-env.d.tspicked up a generated route-types reference (.next/dev/types/...) that Next writes on every dev/build and is committed so contributors don't get a dirty tree;tsconfig.jsonwas updated to include that path and switchedjsxtoreact-jsx/ addedtarget: ES2017to match Next 16's expectations.next.config.mjsalso setsagentRules: falsesonext devstops writingAGENTS.md/CLAUDE.mdinto the tree.Route/layout files were updated for Next 16's async
params/searchParams/cookies()/headers()(all now return Promises) —PageProps/PageMetadataPropstypes,[language]layout and pages,not-found.tsx, and the language/theme cookie services.src/middleware.tswas renamed tosrc/proxy.ts(function renamedmiddleware→proxy) to match Next 16's rename of the convention. A handful of client components (footer,debugger-picker,mobile-header, the decoder/encoder input controls,card-toolbar-description-button) haduseEffect-based "copy a prop/browser value into local state" patterns rewritten to sync during render instead (a newuseClientValuehook covers the browser-only-value case);footer.component.tsx'sreact-selectalso gained an explicitinstanceIdso its generated DOM ids don't disagree between SSR and the client's first render.preview.yaml,preview-community.yaml, andproduction.yamlalso gainedpermissions: { contents: read, id-token: write }and two new steps before "Deploy on Vercel": a JFrog CLI setup that exchanges GitHub's OIDC token for short-lived Artifactory credentials (atko-cicprovider), and a step that mints an.npmrcfragment into$RUNNER_TEMPfrom those credentials. The fragment is passed tovercel deployas--build-env NPM_RC=..., which takes precedence over Vercel's project-levelNPM_RC— the actualnpm installfor the deploy runs on Vercel's build machine, not the Actions runner, so that project-level value was the only credential in play and is what was producingnpm error code E401. The credentials never touch the repo tree. The one substantive comment kept (# Artifactory credentials for the @a0 scope) is functional, not explanatory: Artifactory's response starts with@a0:registry=..., and the Vercel CLI reads a--build-envvalue starting with@as a reference to a stored secret, so that line exists purely to keep the first character from being@.Details worth a reviewer's attention:
react@^18only, so this doesn't block a later React 19 move.--webpackis not cosmetic. Removing it would re-enable Turbopack and reintroduce the MDX JSX-runtime crash described above.next-env.d.tsand the lockfile are committed on purpose — both are generated but need to be in the tree so CI and other contributors don't see a dirty diff after their first build.🔮 Type of Change
Dependency/build-tooling patch plus the App Router API changes it forced. No product surface, no intentional runtime/behavior changes, no public API changes — the render-timing and
react-selectfixes are defensive corrections surfaced while QAing the upgrade, not new features.🔗 References
📖 Documentation
No update needed — the only public-facing entry point (
npm run lint) still means "lint the project"; its implementation changed but not its contract.🎯 Testing
npm run build(afterrm -rf .next) — exit 0.✓ Compiled successfully in 8.7s,✓ Generating static pages using 9 workers (23/23) in 274ms, 23 App Router routes.npm run lint(eslint .) — exit 0, zero findings.npx vitest run— 11 files, 102 tests, all passing, 577ms.npm run dev—✓ Ready in 221ms;GET /→200(next.js: 7.4s, proxy.ts: 94ms, generate-params: 740ms, application-code: 347ms), no compile or console errors in the dev log.npm audit—nextno longer appears; 16 unrelated advisories remain (babel, vitest/vite, esbuild, nanoid, node-forge, svgo, yaml, etc.) and are out of scope here.Gaps a reviewer should know about:
Playwright's browser suite (
tests.yaml) was not re-run in this pass — CI will exercise it.production.yamlonly triggers on push tomaster/production(or schedule/workflow_dispatch), so its deploy path — including the new JFrog steps — is unverified by this PR directly; it runs for the first time on merge.I could not find the advisory's patched-versions field in this repo/session — please confirm
16.3.3is listed before merging.I described how I tested these changes.
This change has test coverage, or I explained why it does not.
🚀 Deployment
Deployable at any time.
16.3.3raises the Node floor to>=20.9.0(up from14.x's lower floor);tests.yaml/production.yamlalready run Node22, so this isn't a blocker, but it's worth confirming Vercel's project-level Node setting is ≥20.9 too —engines.nodewas deliberately left untouched (an open-ended range would let Vercel silently resolve to whatever the latest major is at deploy time). Theatko-cicOIDC provider must already trust this repo, or the "Setup JFrog CLI" step fails outright — worth a quick check with JFrog admin access before merging if this hasn't been exercised yet.🔥 Rollback
Revert this PR's commit(s) to return to
next@14.2.35. Rollback restores a previously-working state (no new prod-only behavior was introduced ahead of this PR), so there's no residual-risk window — the deploy-workflow permissions/JFrog steps are additive and safe to leave in place even if thenextbump itself were reverted.