Skip to content

🔒 add no-unauth-routes lint check#2334

Merged
andrew-bierman merged 3 commits into
feat/checks-backlog-castsfrom
feat/no-unauth-routes
Apr 26, 2026
Merged

🔒 add no-unauth-routes lint check#2334
andrew-bierman merged 3 commits into
feat/checks-backlog-castsfrom
feat/no-unauth-routes

Conversation

@andrew-bierman
Copy link
Copy Markdown
Collaborator

Summary

  • Adds scripts/lint/no-unauth-routes.ts — scans packages/api/src/routes/**/*.ts for Elysia route handlers missing all three auth macros (isAuthenticated, isAdmin, isValidApiKey) with no // public-route: opt-out annotation
  • Excludes admin/ subtree (uses Cloudflare Access + Basic/JWT auth via onBeforeHandle, not Elysia macros — correct by design)
  • Annotates the 10 intentionally-public auth routes (login, register, verify-email, resend-verification, forgot-password, reset-password, refresh, logout, apple sign-in, google sign-in) with descriptive // public-route: reasons
  • Wired into check-all.ts, lint:custom, lefthook.yml pre-push gate, and CI

How it works

  • Regex matches .get('/'…, .post('/… etc. — requiring a / prefix on the path string to avoid false positives from URLSearchParams.get('key') calls
  • Paren-depth tracking extracts the full call span without an AST parser
  • Checks both inside the span and in the preceding run of comment lines (up to 10 lines back) for the // public-route: annotation

Test plan

  • bun scripts/lint/no-unauth-routes.ts exits 0
  • Add a bare .get('/test', () => {}) to any route file → script exits 1 and names it
  • Add // public-route: reason above it → exits 0 again

🤖 Generated with Claude Code

Copilot AI review requested due to automatic review settings April 26, 2026 21:24
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 26, 2026

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 91f58574-d44b-4cb7-8439-7f9733d79a13

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/no-unauth-routes

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.

@github-actions github-actions Bot added dependencies Pull requests that update a dependency file api ci/cd labels Apr 26, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 26, 2026

Coverage Report for API Unit Tests Coverage (./packages/api)

Status Category Percentage Covered / Total
🔵 Lines 75.74% 609 / 804
🔵 Statements 75.74% (🎯 65%) 609 / 804
🔵 Functions 95.91% 47 / 49
🔵 Branches 88.23% 270 / 306
File CoverageNo changed files found.
Generated in workflow #842 for commit 482f326 by the Vitest Coverage Report Action

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 26, 2026

Coverage Report for Expo Unit Tests Coverage (./apps/expo)

Status Category Percentage Covered / Total
🔵 Lines 81.4% 521 / 640
🔵 Statements 81.4% (🎯 75%) 521 / 640
🔵 Functions 92.85% 52 / 56
🔵 Branches 92.55% 199 / 215
File CoverageNo changed files found.
Generated in workflow #842 for commit 482f326 by the Vitest Coverage Report Action

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Adds a custom lint check to prevent accidentally-public API endpoints by scanning Elysia route definitions in packages/api/src/routes/** and requiring an auth macro or an explicit opt-out annotation.

Changes:

  • Added scripts/lint/no-unauth-routes.ts to detect routes missing isAuthenticated, isAdmin, and isValidApiKey unless annotated with // public-route: ....
  • Wired the new check into check-all, lint:custom, lefthook pre-push, and GitHub Actions.
  • Annotated intentionally-public auth endpoints with // public-route: reasons.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
scripts/lint/no-unauth-routes.ts New lint script to flag unauthenticated Elysia routes unless explicitly annotated.
scripts/check-all.ts Registers the new lint script in the unified custom checks runner.
packages/api/src/routes/auth/index.ts Adds // public-route: annotations for intentionally public auth endpoints.
package.json Adds the new lint script to lint:custom.
lefthook.yml Adds the new lint script to the pre-push gate.
.github/workflows/checks.yml Adds CI invocation for the new lint script (currently duplicated with lint:custom).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

function extractRoutePath(content: string, afterOffset: number): string {
// Extract the string literal that is the first argument of the route call.
const slice = content.slice(afterOffset, afterOffset + 200);
const m = slice.match(/^['"`]([^'"`\n]*)/);
Comment on lines +54 to +55
- name: Check for unauthenticated routes
run: bun scripts/lint/no-unauth-routes.ts
@andrew-bierman andrew-bierman force-pushed the feat/checks-backlog-casts branch from 1b404df to 8241453 Compare April 26, 2026 21:30
@andrew-bierman andrew-bierman force-pushed the feat/no-unauth-routes branch from cc4f0cc to 04caea9 Compare April 26, 2026 21:30
@andrew-bierman andrew-bierman force-pushed the feat/checks-backlog-casts branch from 8241453 to 5636103 Compare April 26, 2026 21:39
…acros

Adds scripts/lint/no-unauth-routes.ts which scans packages/api/src/routes
for Elysia route handlers (.get/.post/.put/.patch/.delete/.all) that lack
isAuthenticated/isAdmin/isValidApiKey and have no // public-route: annotation.

- Excludes the admin/ subtree (uses Cloudflare Access + Basic/JWT auth via
  onBeforeHandle, not Elysia macros)
- Annotates the 10 intentionally-public auth routes (login, register,
  verify-email, resend-verification, forgot-password, reset-password,
  refresh, logout, apple, google) with descriptive // public-route: reasons
- Wired into check-all.ts, lint:custom, lefthook.yml pre-push gate, and CI
@andrew-bierman andrew-bierman force-pushed the feat/no-unauth-routes branch from 04caea9 to 4c70867 Compare April 26, 2026 21:40
- no-duplicate-guards.ts: use template literal for path separator (useTemplate)
- no-unauth-routes.ts: restructure while loop to for(;;) to avoid noAssignInExpressions
The /alltrails/preview endpoint is a link-preview proxy that fetches
OG metadata from AllTrails. No user data is accessed or modified,
so it intentionally omits auth macros.
@andrew-bierman andrew-bierman merged commit 0f07bef into feat/checks-backlog-casts Apr 26, 2026
7 checks passed
@andrew-bierman andrew-bierman deleted the feat/no-unauth-routes branch April 26, 2026 22:14
andrew-bierman added a commit that referenced this pull request May 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

api ci/cd dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants