fix: add NextjsGrader check for getSignInUrl in Server Components#110
Open
fix: add NextjsGrader check for getSignInUrl in Server Components#110
Conversation
- Add exported findUnsafeGetSignInUrlUsage() helper that scans .tsx files for getSignInUrl() invocations without top-level 'use client' or 'use server' directives - Add hasTopLevelDirective() with module prologue detection (strips comments/whitespace, ignores inline 'use server' in function bodies) - Wire check into grade() after AuthKitProvider check - Add 7 unit tests covering: server page, shared component, client component, top-level server action, inline server action trap, no usage, and comment mention edge case Addresses Alexander Southgate's friction log where the agent generated nav-auth.tsx as a Server Component calling getSignInUrl().
The invocation regex matched getSignInUrl() inside comments, causing false positives on files with commented-out examples or TODOs like "// don't call getSignInUrl() here". Strip single-line and multi-line comments before testing the regex. Add test case for this edge case.
The test fixture previously only imported getSignInUrl without calling it. Now includes an actual getSignInUrl() call inside an onClick handler to properly exercise the directive detection logic.
- Combine two-pass comment stripping into single regex - Use path.relative() instead of fragile string replacement
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.
Summary
When running
workos installon a Next.js B2B app, the installer agent could generatenav-auth.tsxas a Server Component callinggetSignInUrl(). This adds a structural check to theNextjsGraderthat catches this anti-pattern during end-to-end evals.Changes
nextjs.grader.tsfindUnsafeGetSignInUrlUsage(workDir)— exported helper that scans.tsxfiles underapp/andsrc/app/forgetSignInUrl()invocations in server-rendered components. The detection is layered:/\bgetSignInUrl\s*\(/) — matches actual calls, not imports, variable names, or prose mentionsstripComments()) — removes//and/* */comments before testing the regex, preventing false positives on commented-out calls, TODOs, or remediation noteshasTopLevelDirective()) — checks the module prologue only (strips leading comments/whitespace, then checks if file starts with directive). Inline'use server'in function bodies does NOT count as safe — this catches the case where a page callsgetSignInUrl()at render level but also has an inline server action.tsx-only glob — route handlers are.tsby convention and naturally excludedThe check is wired into
grade()after theAuthKitProvidercheck, producing a grade check named "No getSignInUrl in Server Components". It passes when no unsafe usage is found (including when the agent uses the preferreduseAuth()+refreshAuthclient-side pattern andgetSignInUrldoesn't appear at all).Unit tests (8 cases)
getSignInUrl()inapp/page.tsxgetSignInUrl()in sharednav-auth.tsx'use server'with render-levelgetSignInUrl()'use client'component withgetSignInUrl()call'use server'filegetSignInUrl()anywhererefreshAuthclient-side only()getSignInUrl()callsCompanion PR: workos/skills#13 (reference guide + eval cases)