Skip to content

Use username-scoped public URLs - #453

Merged
kentcdodds merged 7 commits into
mainfrom
cursor/username-public-urls-f0f4
May 12, 2026
Merged

kentcdodds merged 7 commits into
mainfrom
cursor/username-public-urls-f0f4

Conversation

@kentcdodds

@kentcdodds kentcdodds commented May 12, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Switch package app, package invocation, and remote connector public URLs to username-scoped paths.
  • Resolve username to stable internal user IDs at ingress boundaries while keeping Durable Object and data access scoped by user ID.
  • Update generated hosted URLs, asset routing, docs, and tests to only describe the new URL shapes.

Validation

  • npm run validate passes.
  • Manual browser walkthrough confirms the Remote connectors page generates ws://localhost:3742/@kentcdodds/connectors/manual-demo/default-demo.

username_connector_url_playwright.webm

Open in Web Open in Cursor 

Summary by CodeRabbit

  • New Features

    • Public routes, package app URLs, and copyable connector links now use human-readable usernames in their paths.
    • Hosted package URLs are now tied to a resolved username and may be omitted when no username is available.
  • Bug Fixes

    • Endpoint validation tightened: requests with mismatched usernames now return 404.
  • Documentation & Tests

    • Docs, examples, and tests updated to reflect the username-scoped URL patterns.

Review Change Stack

Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@coderabbitai

coderabbitai Bot commented May 12, 2026 •

Copy link
Copy Markdown

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: c0608491-f176-400d-bfb5-4cdb5ed44702

📥 Commits

Reviewing files that changed from the base of the PR and between d3621d0 and b1190f0.

📒 Files selected for processing (2)
  • packages/worker/src/index.ts
  • packages/worker/src/mcp/tools/search.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/worker/src/mcp/tools/search.ts

📝 Walkthrough

Walkthrough

This PR changes public routing from stable user IDs to username-prefixed paths (/@{username}/...) for remote connectors, package apps, and package-invocation endpoints; adds shared public-URL builders; threads public username into caller contexts; and updates parsing, authorization, tests, docs, and Wrangler routing.

Changes

Username-scoped routing refactor

Layer / File(s) Summary
Schema, types, and shared URL builders
packages/shared/src/chat.ts, packages/shared/src/public-urls.ts
Added optional username to McpUserContext. Introduced buildUsernamePathPrefix(), buildPackageAppPath(), buildPackageAppUrl(), and requireUsernameForPublicUrl() helpers.
Remote connector ingress path builders & parser
packages/shared/src/remote-connectors.ts, packages/worker/src/remote-connector/connector-session-key.ts, related tests
userScopedConnectorIngressPath/userScopedConnectorWebSocketUrl now use username and build /@{username}/connectors/{kind}/{instanceId}. Parser and tests updated to extract username, kind, instanceId, and rest.
Worker router & connector proxy
packages/worker/src/index.ts, packages/worker/src/app/router.ts
Added namespaced path predicates, handleUserScopedConnectorRequest to validate+proxy connector WebSocket requests (user lookup, session key, forward-path rewrite, header injection), and wired early returns/404s for namespaced endpoints. Default handler now emits explicit 404.
Package app parsing & access control
packages/worker/src/app/handlers/package-app.ts, tests
parsePackageAppPath now extracts and validates @username and kodyId; handlePackageAppRequest requires URL username match to signed-in user (404 on mismatch) and includes username in caller context. Tests updated.
Package-invocation API routing & validation
packages/worker/src/package-invocations/http.ts, tests
parsePackageInvocationPath parses /@{username}/api/package-invocations/:kodyId/:exportName. Handler verifies route username maps to token-scoped user via findPublicUserIdentityByUsername, logs an audit and returns 404 on mismatch; invoke payloads/tests updated.
Public user lookup & OAuth
packages/worker/src/app/user-lookup.ts, packages/worker/src/oauth-handlers.ts
Added PublicUserIdentity, findPublicUserIdentityByUsername, and resolvePublicUsername. OAuth now validates and propagates approved username into authorization completion and /api/me. Tests updated with richer user mocks.
Account remote connectors UI & API
packages/worker/client/routes/account-remote-connectors.tsx, packages/worker/src/app/handlers/account-remote-connectors.ts, tests
Client and handler payloads switched to username (removing userId). Connector URL generation uses username-based builders and UI copy updated. Tests adjusted.
Caller-context propagation across runtimes
multiple package-runtime and service files
Propagated optional username into createMcpCallerContext across package jobs, invocations, retrievers, runtime bridges, workflows, services, and realtime sessions. createPackageAppCallerContext accepts user.username?: string.
Search & open-generated-ui hosted URL generation
packages/worker/src/mcp/tools/*
Search and open-generated-ui resolve a public username via resolvePublicUsername and use buildPackageAppUrl to generate hosted package URLs. toSlimStructuredMatches accepts optional username and emits hostedUrl only when username present. Tests updated to assert prefixed or null hosted URLs.
Docs, Wrangler routing, tests, CI
docs/contributing/*, packages/worker/wrangler.jsonc, e2e/*, tests
Docs updated to reflect @{username} routes. Wrangler assets.run_worker_first expanded to include "/@*/connectors/*", "/@*/api/package-invocations/*", and "/@*/packages/*" in all envs. Security, e2e, and CI tests updated to seed usernames and assert new URL patterns.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

  • kentcdodds/kody#426: Modifies the package-app handler and tests; touches similar package-app handling and tests.
  • kentcdodds/kody#61: Related to authenticated-user handling and MCP user payload shape changes.
  • kentcdodds/kody#275: Introduced package-invocation endpoints that this PR restructures to use username-scoped routes.

Poem

🐰 I hopped through paths with joyful cheer,
IDs became names and routes grew clear.
Connectors, packages, and invocations too,
Now meet the world at /@username/ — hooroo! 🥕

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 1.96% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the primary objective of the PR: switching to username-scoped public URLs across package apps, package invocations, and remote connectors.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch cursor/username-public-urls-f0f4

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.

cursoragent and others added 3 commits May 12, 2026 19:01
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds marked this pull request as ready for review May 12, 2026 19:21
@github-actions

github-actions Bot commented May 12, 2026 •

Copy link
Copy Markdown
Contributor

🔎 Preview deployed: https://kody-pr-453.kentcdodds.workers.dev

Worker: kody-pr-453
D1: kody-pr-453-db
KV: kody-pr-453-oauth-kv

Mocks:

Comment thread packages/worker/src/mcp/tools/search.ts Outdated
Comment thread packages/worker/src/mcp/tools/search.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (7)
packages/worker/src/oauth-handlers.workers.test.ts (1)

239-268: ⚡ Quick win

Assert username propagation in the existing-session authorize test.

Given this PR’s URL identity shift, this test should verify props.username (and displayName) passed to completeAuthorization, not just that options were captured.

Suggested patch
 	expect(response.status).toBe(200)
 	const payload = await response.json()
 	expect(payload).toEqual({
 		ok: true,
 		redirectTo: 'https://example.com/callback?code=session',
 	})
 	expect(capturedOptions).not.toBeNull()
+	expect(capturedOptions?.props).toMatchObject({
+		email: 'user@example.com',
+		username: 'test-user',
+		displayName: 'test-user',
+	})
 })
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/oauth-handlers.workers.test.ts` around lines 239 - 268,
Update the existing test "authorize allows approval with an existing session" to
assert that the session's username and displayName are propagated into the
options passed to completeAuthorization: after the capturedOptions check, assert
capturedOptions!.props.username === 'user@example.com' and
capturedOptions!.props.displayName === 'user@example.com' (using the same
identity from createAuthCookie) so completeAuthorization receives the expected
props; reference the test, capturedOptions variable, and completeAuthorization
handler to locate where to add these assertions.
packages/worker/src/remote-connector/remote-connectors-shared.node.test.ts (1)

37-46: ⚡ Quick win

Consider adding edge-case tests for username handling.

The test validates the happy path with a simple alphanumeric username ('user-aaa'), but doesn't cover edge cases that could expose validation or encoding issues:

  • Usernames with special characters (e.g., user@domain, user-name.test)
  • Empty or whitespace-only usernames
  • Usernames with characters that require URL encoding
  • Very long usernames
🧪 Example edge-case tests to add
+test('userScopedConnectorWebSocketUrl handles special characters in username', () => {
+	expect(
+		userScopedConnectorWebSocketUrl({
+			origin: 'wss://kody.example.com/',
+			username: 'user-with.dots',
+			kind: 'Lights',
+			instanceId: 'living room',
+		}),
+	).toBe('wss://kody.example.com/@user-with.dots/connectors/lights/living%20room')
+})
+
+test('userScopedConnectorWebSocketUrl rejects empty username', () => {
+	expect(() =>
+		userScopedConnectorWebSocketUrl({
+			origin: 'wss://kody.example.com/',
+			username: '',
+			kind: 'Lights',
+			instanceId: 'living room',
+		}),
+	).toThrow()
+})
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/remote-connector/remote-connectors-shared.node.test.ts`
around lines 37 - 46, Add edge-case unit tests for
userScopedConnectorWebSocketUrl that verify username handling: test that special
characters are percent-encoded (e.g., 'user@domain' yields 'user%40domain' in
the URL and 'user.name' and '-' are preserved/encoded as appropriate), test that
spaces are encoded (e.g., 'user name' -> 'user%20name'), add a test asserting
the function rejects or throws for empty or whitespace-only usernames, and add a
test with a very long username to ensure it is preserved/encoded rather than
truncated; reference the userScopedConnectorWebSocketUrl helper in
remote-connectors-shared.node.test.ts when adding these assertions.
packages/worker/src/mcp/tools/search.ts (1)

174-179: ⚡ Quick win

Consider consolidating duplicate username validation helpers.

This helper performs the same validation as requireSavedPackageAppUsername in open-generated-ui.ts. Extract a shared utility to eliminate duplication.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/mcp/tools/search.ts` around lines 174 - 179, The function
requireUsernameForHostedPackageUrl duplicates validation already implemented by
requireSavedPackageAppUsername (in open-generated-ui.ts); extract a shared
utility (e.g., requireUsername or validateUsernamePresence) into a common module
and replace both requireUsernameForHostedPackageUrl and
requireSavedPackageAppUsername to call that single shared function to remove
duplication and centralize the error message/behavior.
packages/worker/src/mcp/tools/open-generated-ui.ts (2)

84-89: ⚡ Quick win

Consider consolidating duplicate username validation helpers.

This helper does the same validation as requireUsernameForHostedPackageUrl in search.ts and search-format.ts. Consider extracting a shared utility (e.g., in packages/shared/src/public-urls.ts alongside buildPackageAppUrl) to eliminate duplication and ensure consistent error messages.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/mcp/tools/open-generated-ui.ts` around lines 84 - 89, The
helper requireSavedPackageAppUsername duplicates validation logic present in
requireUsernameForHostedPackageUrl (used in search.ts and search-format.ts);
extract a shared validator (e.g., validatePackageAppUsername or
requireUsernameForPackageUrls) into the shared module alongside
buildPackageAppUrl (suggested location: packages/shared/src/public-urls.ts) and
replace both requireSavedPackageAppUsername and
requireUsernameForHostedPackageUrl with calls to the new shared function so all
callers share the same validation and error message.

129-138: ⚡ Quick win

Redundant username validation before calling the helper.

The validation at lines 130-132 checks the same condition that requireSavedPackageAppUsername checks at line 136. When line 136 executes (inside the savedPackage ? ... : null ternary), you've already guaranteed that username is truthy, so the helper's validation can never throw.

Recommendation: Remove lines 130-132 and let the helper handle all validation, or remove the helper call and keep the early validation.

♻️ Simplified approach
 		const username = callerContext.user?.username ?? null
-		if (savedPackage && !username) {
-			throw new Error('Username is required to open saved package apps.')
-		}
 		const hostedUrl = savedPackage
 			? buildPackageAppUrl({
 					origin: agent.requireDomain(),
 					username: requireSavedPackageAppUsername(username),
 					kodyId: savedPackage.kodyId,
 				})
 			: null
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/mcp/tools/open-generated-ui.ts` around lines 129 - 138,
The code redundantly checks username before calling
requireSavedPackageAppUsername; remove the early check (the if block that throws
when savedPackage && !username) and let requireSavedPackageAppUsername perform
validation, keeping the ternary that calls buildPackageAppUrl with
requireSavedPackageAppUsername(username) and savedPackage.kodyId unchanged.
packages/worker/src/mcp/tools/search-format.ts (1)

417-424: ⚡ Quick win

Consider consolidating duplicate username validation helpers.

This is the third instance of the same username validation logic (also in open-generated-ui.ts and search.ts). Extract a shared utility to eliminate duplication and ensure consistent error messages across all username-scoped URL construction.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/mcp/tools/search-format.ts` around lines 417 - 424,
Extract the duplicate username validation into a single exported helper (e.g.,
validateUsernameOrThrow) and replace the three copies
(requireUsernameForHostedPackageUrl in search-format.ts plus variants in
open-generated-ui.ts and search.ts) with imports of the new utility; ensure the
helper signature accepts (username: string | null | undefined) and throws the
consistent Error('Username is required to build hosted package app URLs.') so
all callers share identical behavior and message, then update the three call
sites to use the new helper and remove the local duplicates.
packages/worker/src/index.ts (1)

88-118: 💤 Low value

Consider error handling for user lookup failures.

The findPublicUserIdentityByUsername call (line 97) will throw on database errors, resulting in a 500 response instead of 404. While this matches the current error handling pattern, you may want to explicitly catch and handle database errors to return 404 consistently.

🛡️ Optional defensive error handling
 	const routeUser = await findPublicUserIdentityByUsername({
 		db: env.APP_DB,
 		username: userScopedConnectorRoute.username,
-	})
+	}).catch((error) => {
+		console.error('Failed to lookup user for connector route:', error)
+		return null
+	})
 	if (!routeUser) {
 		return new Response('Not Found', { status: 404 })
 	}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/worker/src/index.ts` around lines 88 - 118, The call to
findPublicUserIdentityByUsername inside handleUserScopedConnectorRequest can
throw on DB errors and cause a 500; wrap that call in a try/catch, and if it
throws treat it the same as a missing user by returning a 404 (optionally log
the error via processLogger or env logger) so the function returns a Not Found
instead of propagating a 500; ensure you catch around the
findPublicUserIdentityByUsername invocation and keep the rest of the logic
(sessionKey generation, REMOTE_CONNECTOR_SESSION stub lookup, forwardRequest
creation) unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/oauth-handlers.ts`:
- Around line 660-666: The early-return when the session user is not found (in
the createDb(...)/db.findOne(usersTable, ...) branch) skips audit logging;
before calling respondAuthorizeError('Signed-in user not found.', 401) add a
call to the audit logging helper (e.g., logAuditEvent or the project’s audit
logger) with context such as event type "oauth.authorize_failed", reason
"session user not found", the sessionEmail, request info, and status 401 so the
failure is recorded; ensure the audit call runs synchronously/awaited if
logAuditEvent is async and keep the existing respondAuthorizeError call
afterwards.

---

Nitpick comments:
In `@packages/worker/src/index.ts`:
- Around line 88-118: The call to findPublicUserIdentityByUsername inside
handleUserScopedConnectorRequest can throw on DB errors and cause a 500; wrap
that call in a try/catch, and if it throws treat it the same as a missing user
by returning a 404 (optionally log the error via processLogger or env logger) so
the function returns a Not Found instead of propagating a 500; ensure you catch
around the findPublicUserIdentityByUsername invocation and keep the rest of the
logic (sessionKey generation, REMOTE_CONNECTOR_SESSION stub lookup,
forwardRequest creation) unchanged.

In `@packages/worker/src/mcp/tools/open-generated-ui.ts`:
- Around line 84-89: The helper requireSavedPackageAppUsername duplicates
validation logic present in requireUsernameForHostedPackageUrl (used in
search.ts and search-format.ts); extract a shared validator (e.g.,
validatePackageAppUsername or requireUsernameForPackageUrls) into the shared
module alongside buildPackageAppUrl (suggested location:
packages/shared/src/public-urls.ts) and replace both
requireSavedPackageAppUsername and requireUsernameForHostedPackageUrl with calls
to the new shared function so all callers share the same validation and error
message.
- Around line 129-138: The code redundantly checks username before calling
requireSavedPackageAppUsername; remove the early check (the if block that throws
when savedPackage && !username) and let requireSavedPackageAppUsername perform
validation, keeping the ternary that calls buildPackageAppUrl with
requireSavedPackageAppUsername(username) and savedPackage.kodyId unchanged.

In `@packages/worker/src/mcp/tools/search-format.ts`:
- Around line 417-424: Extract the duplicate username validation into a single
exported helper (e.g., validateUsernameOrThrow) and replace the three copies
(requireUsernameForHostedPackageUrl in search-format.ts plus variants in
open-generated-ui.ts and search.ts) with imports of the new utility; ensure the
helper signature accepts (username: string | null | undefined) and throws the
consistent Error('Username is required to build hosted package app URLs.') so
all callers share identical behavior and message, then update the three call
sites to use the new helper and remove the local duplicates.

In `@packages/worker/src/mcp/tools/search.ts`:
- Around line 174-179: The function requireUsernameForHostedPackageUrl
duplicates validation already implemented by requireSavedPackageAppUsername (in
open-generated-ui.ts); extract a shared utility (e.g., requireUsername or
validateUsernamePresence) into a common module and replace both
requireUsernameForHostedPackageUrl and requireSavedPackageAppUsername to call
that single shared function to remove duplication and centralize the error
message/behavior.

In `@packages/worker/src/oauth-handlers.workers.test.ts`:
- Around line 239-268: Update the existing test "authorize allows approval with
an existing session" to assert that the session's username and displayName are
propagated into the options passed to completeAuthorization: after the
capturedOptions check, assert capturedOptions!.props.username ===
'user@example.com' and capturedOptions!.props.displayName === 'user@example.com'
(using the same identity from createAuthCookie) so completeAuthorization
receives the expected props; reference the test, capturedOptions variable, and
completeAuthorization handler to locate where to add these assertions.

In `@packages/worker/src/remote-connector/remote-connectors-shared.node.test.ts`:
- Around line 37-46: Add edge-case unit tests for
userScopedConnectorWebSocketUrl that verify username handling: test that special
characters are percent-encoded (e.g., 'user@domain' yields 'user%40domain' in
the URL and 'user.name' and '-' are preserved/encoded as appropriate), test that
spaces are encoded (e.g., 'user name' -> 'user%20name'), add a test asserting
the function rejects or throws for empty or whitespace-only usernames, and add a
test with a very long username to ensure it is preserved/encoded rather than
truncated; reference the userScopedConnectorWebSocketUrl helper in
remote-connectors-shared.node.test.ts when adding these assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ff5a87ac-1bb9-46c9-8076-b0d330b156dc

📥 Commits

Reviewing files that changed from the base of the PR and between f2ddf85 and 7986542.

📒 Files selected for processing (42)
  • docs/contributing/architecture/data-storage.md
  • docs/contributing/architecture/remote-connectors.md
  • docs/contributing/architecture/request-lifecycle.md
  • docs/contributing/package-invocation-api.md
  • docs/contributing/security.md
  • e2e/remote-connectors.spec.ts
  • packages/shared/src/chat.ts
  • packages/shared/src/public-urls.ts
  • packages/shared/src/remote-connectors.ts
  • packages/worker/client/routes/account-remote-connectors.tsx
  • packages/worker/src/app/authenticated-user.ts
  • packages/worker/src/app/handlers/account-remote-connectors.node.test.ts
  • packages/worker/src/app/handlers/account-remote-connectors.ts
  • packages/worker/src/app/handlers/package-app.node.test.ts
  • packages/worker/src/app/handlers/package-app.ts
  • packages/worker/src/app/router.ts
  • packages/worker/src/app/user-lookup.ts
  • packages/worker/src/index.ts
  • packages/worker/src/jobs/service.ts
  • packages/worker/src/mcp/generated-ui-api.ts
  • packages/worker/src/mcp/tools/open-generated-ui.node.test.ts
  • packages/worker/src/mcp/tools/open-generated-ui.ts
  • packages/worker/src/mcp/tools/search-format.node.test.ts
  • packages/worker/src/mcp/tools/search-format.ts
  • packages/worker/src/mcp/tools/search.ts
  • packages/worker/src/oauth-handlers.ts
  • packages/worker/src/oauth-handlers.workers.test.ts
  • packages/worker/src/package-invocations/http.ts
  • packages/worker/src/package-invocations/http.workers.test.ts
  • packages/worker/src/package-invocations/service.ts
  • packages/worker/src/package-retrievers/service.ts
  • packages/worker/src/package-runtime/package-app.ts
  • packages/worker/src/package-runtime/package-service.ts
  • packages/worker/src/package-runtime/package-workflows.ts
  • packages/worker/src/package-runtime/realtime-session.ts
  • packages/worker/src/remote-connector/connector-session-key.node.test.ts
  • packages/worker/src/remote-connector/connector-session-key.ts
  • packages/worker/src/remote-connector/remote-connectors-shared.node.test.ts
  • packages/worker/src/remote-connector/session.ts
  • packages/worker/src/security/public-route-hardening.workers.test.ts
  • packages/worker/wrangler.jsonc
  • tools/ci/resource-utils.node.test.ts

Comment thread packages/worker/src/oauth-handlers.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/app/user-lookup.ts`:
- Around line 41-45: The code prematurely returns any non-empty input.username
(variable username) and thus skips fallback DB resolution; modify the
early-return in the function in user-lookup.ts to validate the trimmed username
(e.g., with the existing validateUsername or a username regex) before returning
it, and if validation fails continue to the fallback path (email -> DB lookup)
so stale/invalid usernames do not bypass lookupUserByUsername or the public URL
generation logic.

In `@packages/worker/src/mcp/tools/search.ts`:
- Around line 1682-1687: hostedUrl construction currently calls
requireUsernameForPublicUrl and can throw when input.username is missing; change
the logic so hostedUrl is only computed when record.hasApp AND a username is
available (or compute a safeUsername via a non-throwing check) — update the
hostedUrl expression that calls buildPackageAppUrl to first verify
input.username (or use a safe getter) instead of invoking
requireUsernameForPublicUrl directly, or wrap the call in a short try/catch that
returns undefined on failure so the package entity lookup won't hard-fail.

In `@packages/worker/src/oauth-handlers.ts`:
- Line 658: The assignment approvedUsername = userRecord.username must validate
that userRecord.username is a non-empty string before using it downstream (e.g.,
for displayName and props.username); update the logic in the OAuth handling flow
(the approvedUsername assignment site and any code that sets
displayName/props.username) to check typeof userRecord.username === 'string' &&
userRecord.username.trim() !== '' and either use a safe fallback (such as
userRecord.email, a generated fallback, or undefined) or abort with a clear
error/validation response when the username is missing/empty so downstream
consumers never receive null/empty usernames.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 999e9ec4-3c09-4555-935e-5fd7020f3f85

📥 Commits

Reviewing files that changed from the base of the PR and between 7986542 and 6515aaf.

📒 Files selected for processing (8)
  • packages/shared/src/public-urls.ts
  • packages/worker/src/app/user-lookup.ts
  • packages/worker/src/mcp/tools/open-generated-ui.node.test.ts
  • packages/worker/src/mcp/tools/open-generated-ui.ts
  • packages/worker/src/mcp/tools/search-format.node.test.ts
  • packages/worker/src/mcp/tools/search-format.ts
  • packages/worker/src/mcp/tools/search.ts
  • packages/worker/src/oauth-handlers.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/shared/src/public-urls.ts

Comment thread packages/worker/src/app/user-lookup.ts
Comment thread packages/worker/src/mcp/tools/search.ts Outdated
Comment thread packages/worker/src/oauth-handlers.ts Outdated
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

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 current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/worker/src/mcp/tools/search.ts`:
- Around line 1794-1799: resolvePublicUsername is being called before validation
and outside the main try/catch, so failures in that lookup can short-circuit and
bypass the structured validation/error handling; move the call to
resolvePublicUsername into the handled path (inside the try/catch and after the
args validation) and only invoke it when needed (e.g., before building the
search context) so errors are caught and returned via the existing error
handling; update references around callerContext.user and agent.getEnv().APP_DB
to use the resolved username variable within the try block where search logic
(the code that checks !args.query && !args.entity and subsequent handling)
executes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 586ae4cf-65c2-4a80-aa3e-acda09fc38f7

📥 Commits

Reviewing files that changed from the base of the PR and between 6515aaf and d3621d0.

📒 Files selected for processing (3)
  • packages/worker/src/app/user-lookup.ts
  • packages/worker/src/mcp/tools/search.ts
  • packages/worker/src/oauth-handlers.ts
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/worker/src/app/user-lookup.ts
  • packages/worker/src/oauth-handlers.ts

Comment thread packages/worker/src/mcp/tools/search.ts Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d3621d0. Configure here.

Comment thread packages/worker/src/index.ts
Co-authored-by: Kent C. Dodds <me+github@kentcdodds.com>
@kentcdodds
kentcdodds merged commit 59de708 into main May 12, 2026
5 checks passed
@kentcdodds
kentcdodds deleted the cursor/username-public-urls-f0f4 branch May 12, 2026 21:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants