Skip to content

chore(repo): refactor machine auth tests for Next.js and Astro#8124

Merged
wobsoriano merged 9 commits intomainfrom
rob/machine-auth-e2e-cleanup
Mar 20, 2026
Merged

chore(repo): refactor machine auth tests for Next.js and Astro#8124
wobsoriano merged 9 commits intomainfrom
rob/machine-auth-e2e-cleanup

Conversation

@wobsoriano
Copy link
Member

@wobsoriano wobsoriano commented Mar 19, 2026

Description

Restructures machine auth integration tests from shared machine-auth/ test files into per-SDK test files (next-machine.test.ts, astro/machine.test.ts) for better isolation and maintainability. Adds token type mismatch test coverage to verify that routes correctly reject tokens of the wrong type (e.g., sending an M2M token to an API key route).

This is the start of updating all machine auth e2e tests across SDKs. Other SDKs will follow in a subsequent PR.

Changes

  • Moved shared machine-auth/{api-keys,m2m,oauth}.test.ts to per-SDK files for Next.js and Astro
  • Moved machine-auth/component.test.ts to api-keys-component.test.ts
  • Added machineAuthService.ts test utility
  • Added token type mismatch tests for each auth block (API key, M2M, OAuth). Each route now verifies rejection of both wrong token type prefixes

Test coverage

Next.js (next-machine.test.ts)

  • API key auth
    • Returns 401 if no API key is provided
    • Returns 401 if API key is invalid
    • Returns 200 with auth object if API key is valid
    • Rejects M2M token on API key route (token type mismatch)
    • Rejects OAuth token on API key route (token type mismatch)
    • Handles multiple token types (api_key + session_token)
  • M2M auth
    • Rejects requests with invalid M2M tokens
    • Rejects M2M requests when sender machine lacks access to receiver machine
    • Authorizes M2M requests when sender machine has proper access
    • Authorizes after dynamically granting scope
    • Verifies JWT format M2M token via local verification
    • Rejects API key token on M2M route (token type mismatch)
    • Rejects OAuth token on M2M route (token type mismatch)
  • OAuth auth
    • Verifies valid OAuth access token obtained through authorization flow
    • Rejects request without OAuth token
    • Rejects request with invalid OAuth token
    • Rejects API key token on OAuth route (token type mismatch)
    • Rejects M2M token on OAuth route (token type mismatch)

Astro (astro/machine.test.ts)

  • API key auth
    • Returns 401 if no API key is provided
    • Returns 401 if API key is invalid
    • Returns 200 with auth object if API key is valid
    • Rejects M2M token on API key route (token type mismatch)
    • Rejects OAuth token on API key route (token type mismatch)
  • M2M auth
    • Rejects requests with invalid M2M tokens
    • Rejects M2M requests when sender machine lacks access to receiver machine
    • Authorizes M2M requests when sender machine has proper access
    • Verifies JWT format M2M token via local verification
    • Rejects API key token on M2M route (token type mismatch)
    • Rejects OAuth token on M2M route (token type mismatch)
  • OAuth auth
    • Verifies valid OAuth access token obtained through authorization flow
    • Rejects request without OAuth token
    • Rejects request with invalid OAuth token
    • Rejects API key token on OAuth route (token type mismatch)
    • Rejects M2M token on OAuth route (token type mismatch)

Checklist

  • pnpm test runs as expected.
  • pnpm build runs as expected.
  • (If applicable) JSDoc comments have been added or updated for any package exports
  • (If applicable) Documentation has been updated

Type of change

  • 🐛 Bug fix
  • 🌟 New feature
  • 🔨 Breaking change
  • 📖 Refactoring / dependency upgrade / documentation
  • other:

Summary by CodeRabbit

  • Tests
    • Added a consolidated end-to-end integration suite covering API key, M2M, and OAuth authentication for Next.js.
    • Expanded scenarios: token-type mismatches, token revocation, JWT M2M verification, and full OAuth authorization-code flows.
    • Removed legacy individual machine-auth test files and updated test imports to the centralized setup.
  • Test Utilities
    • Added helpers to create/manage fake machines and OAuth apps, mint M2M (including JWT) tokens, and perform OAuth token exchange.

Restructure machine auth integration tests from shared test files into
per-SDK test files for better isolation and maintainability. Add token
type mismatch coverage to verify routes reject wrong token types
(e.g., M2M token on API key route, API key on OAuth route).

This is the first part of updating all machine auth tests across SDKs.
Express will follow in a subsequent PR.
@vercel
Copy link

vercel bot commented Mar 19, 2026

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

Project Deployment Actions Updated (UTC)
clerk-js-sandbox Ready Ready Preview, Comment Mar 20, 2026 4:11pm

Request Review

@changeset-bot
Copy link

changeset-bot bot commented Mar 19, 2026

⚠️ No Changeset found

Latest commit: d151d2f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@wobsoriano wobsoriano changed the title test(e2e): refactor machine auth tests for Next.js and Astro chore(repo): refactor machine auth tests for Next.js and Astro Mar 19, 2026
@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 19, 2026

Open in StackBlitz

@clerk/agent-toolkit

npm i https://pkg.pr.new/@clerk/agent-toolkit@8124

@clerk/astro

npm i https://pkg.pr.new/@clerk/astro@8124

@clerk/backend

npm i https://pkg.pr.new/@clerk/backend@8124

@clerk/chrome-extension

npm i https://pkg.pr.new/@clerk/chrome-extension@8124

@clerk/clerk-js

npm i https://pkg.pr.new/@clerk/clerk-js@8124

@clerk/dev-cli

npm i https://pkg.pr.new/@clerk/dev-cli@8124

@clerk/expo

npm i https://pkg.pr.new/@clerk/expo@8124

@clerk/expo-passkeys

npm i https://pkg.pr.new/@clerk/expo-passkeys@8124

@clerk/express

npm i https://pkg.pr.new/@clerk/express@8124

@clerk/fastify

npm i https://pkg.pr.new/@clerk/fastify@8124

@clerk/hono

npm i https://pkg.pr.new/@clerk/hono@8124

@clerk/localizations

npm i https://pkg.pr.new/@clerk/localizations@8124

@clerk/nextjs

npm i https://pkg.pr.new/@clerk/nextjs@8124

@clerk/nuxt

npm i https://pkg.pr.new/@clerk/nuxt@8124

@clerk/react

npm i https://pkg.pr.new/@clerk/react@8124

@clerk/react-router

npm i https://pkg.pr.new/@clerk/react-router@8124

@clerk/shared

npm i https://pkg.pr.new/@clerk/shared@8124

@clerk/tanstack-react-start

npm i https://pkg.pr.new/@clerk/tanstack-react-start@8124

@clerk/testing

npm i https://pkg.pr.new/@clerk/testing@8124

@clerk/ui

npm i https://pkg.pr.new/@clerk/ui@8124

@clerk/upgrade

npm i https://pkg.pr.new/@clerk/upgrade@8124

@clerk/vue

npm i https://pkg.pr.new/@clerk/vue@8124

commit: d151d2f

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 19, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new test utility module integration/testUtils/machineAuthService.ts that provides M2M and OAuth helpers and types (machine network creation, JWT M2M token minting, OAuth app creation, and a browser-driven authorization-code flow), and re-exports them from integration/testUtils/index.ts. Removes legacy Playwright test files under integration/tests/machine-auth/ and adds consolidated suites: a new integration/tests/next-machine.test.ts and expanded integration/tests/astro/machine.test.ts that exercise API key, M2M, and OAuth flows. Also updates import paths in one test file.

Possibly related PRs

  • PR 6671 (clerk/javascript): Introduces machine-auth helpers, tests, and changes to locals.auth({ acceptsToken: ... }), directly overlapping the added helpers and updated test routes in this change.
🚥 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 title accurately describes the main structural change: refactoring machine auth tests to be organized per-SDK (Next.js and Astro) rather than in a shared directory.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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


Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@integration/tests/next-machine.test.ts`:
- Around line 102-113: The test loop currently uses hard-coded placeholder
strings ('mt_test_mismatch' and 'oat_test_mismatch') as Bearer tokens, which can
yield false positives; replace these placeholders with real tokens minted by the
project's test auth helper (create/mint a real M2M token and a real OAuth token)
and pass those into the Authorization header in the same test (`test("rejects
${tokenType} token on API key route (token type mismatch)")` that calls
request.get('/api/me', ...) so the route receives a valid-but-wrong-type token;
apply the same replacement to the other occurrences mentioned (the similar cases
around the other ranges) so each mismatch case uses an actual token of the
opposite type.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: d3276979-02af-45ff-b177-26ccfe44610f

📥 Commits

Reviewing files that changed from the base of the PR and between a75d8c1 and 70a5063.

📒 Files selected for processing (3)
  • integration/tests/astro/machine.test.ts
  • integration/tests/express/machine.test.ts
  • integration/tests/next-machine.test.ts

Express machine auth tests will be added in a follow-up PR.
Copy link
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@integration/testUtils/machineAuthService.ts`:
- Around line 59-65: The cleanup block incorrectly awaits each call before
passing results into Promise.all, causing sequential execution; remove the inner
await keywords so Promise.all receives the promise objects directly (e.g., calls
to clerkClient.m2m.revokeToken({ m2mTokenId: scopedSenderToken.id }),
clerkClient.m2m.revokeToken({ m2mTokenId: unscopedSenderToken.id }),
clerkClient.machines.delete(scopedSender.id),
clerkClient.machines.delete(unscopedSender.id), and
clerkClient.machines.delete(primaryServer.id })) and await the Promise.all(...)
result to run them in parallel.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: c3d92403-a1f2-436b-ab3c-d874bf28e29c

📥 Commits

Reviewing files that changed from the base of the PR and between 70a5063 and d1e6035.

📒 Files selected for processing (1)
  • integration/testUtils/machineAuthService.ts

Co-authored-by: Tom Milewski <me@tm.codes>
Copy link
Contributor

@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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@integration/testUtils/machineAuthService.ts`:
- Around line 110-118: The obtainOAuthAccessToken function has three type-safety
gaps: ensure fakeUser.email is non-optional before calling
signInWithEmailAndInstantPassword (either make fakeUser.email required in
ObtainOAuthAccessTokenParams or check/throw if missing), read authCode via
URLSearchParams.get and assert/throw if it's null before using it in the token
request so the compiler knows it's a string, and validate that
tokenData.access_token is present (throw or handle the error) before returning
so the function can keep returning Promise<string>; reference the symbols
fakeUser.email, signInWithEmailAndInstantPassword, authCode (from
URLSearchParams.get), tokenData.access_token, and the obtainOAuthAccessToken
function when making these fixes.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository YAML (base), Organization UI (inherited)

Review profile: ASSERTIVE

Plan: Pro

Run ID: d021c003-8fa2-4ffd-935f-c927b2127347

📥 Commits

Reviewing files that changed from the base of the PR and between 78b502c and d151d2f.

📒 Files selected for processing (1)
  • integration/testUtils/machineAuthService.ts

Comment on lines +110 to +118
export type ObtainOAuthAccessTokenParams = {
page: Page;
oAuthApp: OAuthApplication;
redirectUri: string;
fakeUser: { email?: string; password: string };
signIn: {
waitForMounted: (...args: any[]) => Promise<any>;
signInWithEmailAndInstantPassword: (params: { email: string; password: string }) => Promise<any>;
};
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== tsconfig strictness flags =="
fd 'tsconfig*.json' | while read -r f; do
  echo "--- $f ---"
  python - "$f" <<'PY'
import json,sys
p=sys.argv[1]
try:
    d=json.load(open(p))
    c=d.get("compilerOptions",{})
    print("strict:", c.get("strict"), "strictNullChecks:", c.get("strictNullChecks"))
except Exception as e:
    print("unparseable:", e)
PY
done

echo
echo "== nullable flow in machineAuthService =="
rg -n -C2 "fakeUser: \{ email\?: string; password: string \}|searchParams\.get\('code'\)|code: authCode|return tokenData\.access_token" integration/testUtils/machineAuthService.ts

Repository: clerk/javascript

Length of output: 5798


🏁 Script executed:

cat -n integration/testUtils/machineAuthService.ts | sed -n '135,190p'

Repository: clerk/javascript

Length of output: 2229


🏁 Script executed:

cat -n integration/testUtils/machineAuthService.ts | sed -n '110,120p'

Repository: clerk/javascript

Length of output: 475


🏁 Script executed:

fd machineAuthService -type f

Repository: clerk/javascript

Length of output: 230


🏁 Script executed:

grep -r "machineAuthService" --include="*.ts" --include="*.js" --include="*.json" | head -20

Repository: clerk/javascript

Length of output: 230


🏁 Script executed:

cd integration/testUtils && grep -r "obtainOAuthAccessToken" . && cd - || true

Repository: clerk/javascript

Length of output: 186


🏁 Script executed:

cat -n integration/testUtils/machineAuthService.ts | sed -n '1,20p'

Repository: clerk/javascript

Length of output: 816


Type contract violations in OAuth token helper create potential runtime failures.

The function obtainOAuthAccessToken has three type mismatches that could cause test failures:

  1. fakeUser.email is optional (email?: string, line 114) but passed to signInWithEmailAndInstantPassword which requires a non-null string (line 150-151)
  2. authCode from URLSearchParams.get('code') returns string | null (line 163) but is used directly in the token request payload (line 171) instead of being validated first
  3. Return type declares Promise<string> (line 137) but returns tokenData.access_token which is typed as optional (line 182, 185)

While runtime assertions exist at lines 164 and 183, they do not satisfy the type contracts and will only catch issues if tests actually hit them. Ensure email is required in the parameter type or validate it before use, check that authCode is not null before inclusion in the request, and verify access_token exists before returning.

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

In `@integration/testUtils/machineAuthService.ts` around lines 110 - 118, The
obtainOAuthAccessToken function has three type-safety gaps: ensure
fakeUser.email is non-optional before calling signInWithEmailAndInstantPassword
(either make fakeUser.email required in ObtainOAuthAccessTokenParams or
check/throw if missing), read authCode via URLSearchParams.get and assert/throw
if it's null before using it in the token request so the compiler knows it's a
string, and validate that tokenData.access_token is present (throw or handle the
error) before returning so the function can keep returning Promise<string>;
reference the symbols fakeUser.email, signInWithEmailAndInstantPassword,
authCode (from URLSearchParams.get), tokenData.access_token, and the
obtainOAuthAccessToken function when making these fixes.

@wobsoriano wobsoriano merged commit ad782ff into main Mar 20, 2026
73 of 74 checks passed
@wobsoriano wobsoriano deleted the rob/machine-auth-e2e-cleanup branch March 20, 2026 16:46
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