Skip to content

Conversation

@matt-aitken
Copy link
Member

No description provided.

@changeset-bot
Copy link

changeset-bot bot commented Jan 9, 2026

⚠️ No Changeset found

Latest commit: 4a819fc

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

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Jan 9, 2026

Walkthrough

The changes introduce impersonation as an access control factor in the application's query functionality. The side menu component is updated to display the Query menu item for impersonating users in addition to admins and users with feature flag access. Correspondingly, the query route's hasQueryAccess function is modified to accept an isImpersonating parameter and grant access when impersonation is active, with all call sites updated to pass this new parameter.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning No pull request description was provided; all required sections from the template are missing. Add a complete PR description including the issue number, testing steps, changelog entry, and checklist items as per the repository template.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically describes the main change: allowing query access for impersonating users.

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

✨ Finishing touches
  • 📝 Generate docstrings

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.

@claude
Copy link

claude bot commented Jan 9, 2026

PR Review: Allow query access when impersonating

Summary

This PR extends the Query feature access to include impersonating users, following the same pattern already established in the regions route. The change is minimal (5 additions, 4 deletions across 2 files) and focused.


Code Quality ✅

Strengths:

  • Follows existing patterns: The user.admin || user.isImpersonating pattern is already used in the regions route (apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.regions/route.tsx:75 and :121), making this change consistent with established conventions.
  • Complete coverage: Both the UI layer (SideMenu) and server-side authorization (hasQueryAccess function) are updated consistently.
  • Protects both loader and action: The authorization check is applied to both read and write operations (lines 121 and 162 in the query route).
  • Minimal, focused change: The diff is small and targeted, reducing the risk of introducing bugs.

The implementation correctly:

  1. Updates the hasQueryAccess function signature to accept isImpersonating: boolean parameter
  2. Grants access when isAdmin || isImpersonating is true
  3. Updates both caller sites (loader and action) to pass user.isImpersonating
  4. Updates the SideMenu to show the Query menu item when impersonating

Potential Issues ⚠️

  1. No test coverage added: Authorization logic is security-critical and should have test coverage. Consider adding tests for:

    • Admin users can access Query
    • Impersonating users can access Query
    • Regular users without the feature flag cannot access
    • Regular users with the feature flag can access
  2. Empty PR description: The PR body is empty. It would be helpful to document:

    • Why this feature is needed (use case for support/debugging)
    • Any relevant context about impersonation workflow

Security Considerations 🔒

The change appears safe because:

  • isImpersonating is set server-side in session.server.ts:57 via !!impersonationId
  • The impersonation flow requires prior authentication and admin privileges to initiate
  • The existing pattern is trusted in the regions route

Recommendation: Ensure audit logging is in place for impersonation sessions to track what actions were taken while impersonating. This may already exist elsewhere in the codebase.


Performance ✅

No performance concerns. The change adds a simple boolean check that short-circuits before the database query for feature flags when the user is impersonating.


Verdict

Approve with minor suggestions. The code change itself is correct, follows existing patterns, and is well-implemented. The main suggestions are:

  1. Add the PR description to document the motivation
  2. Consider adding test coverage for the authorization logic (can be a follow-up)

Good work keeping this focused and consistent with existing conventions!

@vibe-kanban-cloud
Copy link

Review Complete

Your review story is ready!

View Story

Comment !reviewfast on this PR to re-generate the story.

@claude
Copy link

claude bot commented Jan 9, 2026

PR Review: Allow query access when impersonating

Summary

This PR extends the Query feature access to users who are impersonating another user, in addition to admins and users with the hasQueryAccess feature flag. This is a small, focused change (5 additions, 4 deletions) that affects 2 files.


✅ Code Quality

The changes follow good practices:

  • Consistent pattern: The isImpersonating check is added consistently in both the UI layer (SideMenu.tsx:277) and the backend access control (route.tsx:83, 121, 162)
  • Clean function signature update: The hasQueryAccess function properly receives isImpersonating as a separate parameter rather than bundling it with isAdmin
  • DRY principle: The access check is centralized in the hasQueryAccess function and reused in both loader and action

✅ Security Considerations

The change looks appropriate from a security perspective:

  • Impersonation is already authenticated: The user.isImpersonating flag comes from requireUser(request), which validates the session
  • Appropriate privilege level: Impersonating users (typically support/admin staff) should have query access to debug customer issues
  • Consistent enforcement: Access is checked in both the loader (page load) and action (query execution), preventing bypass via direct API calls

⚠️ Minor Suggestions

  1. Parameter ordering consideration (route.tsx:77-81):

    async function hasQueryAccess(
      userId: string,
      isAdmin: boolean,
      isImpersonating: boolean,
      organizationSlug: string
    )

    Consider grouping boolean flags together or passing them as an options object for better clarity, especially if more access flags are added in the future:

    async function hasQueryAccess(
      userId: string,
      organizationSlug: string,
      options: { isAdmin: boolean; isImpersonating: boolean }
    )

    This is a minor stylistic suggestion and not blocking.

  2. Documentation: Since this is a security-related change, consider adding a brief comment explaining why impersonating users need query access (e.g., "// Allow impersonating users to access Query for debugging/support purposes").

✅ Potential Bugs

No bugs identified. The logic correctly uses || (OR) to grant access if any of the conditions are true.

✅ Performance

No performance concerns - the isImpersonating check is a simple boolean that short-circuits before any database queries when true.

✅ Test Coverage

The changes are minimal and follow existing patterns. Since this uses an existing isImpersonating flag that's already tested elsewhere, and the access control logic is straightforward, the risk is low. However, if the project has integration tests for the Query feature, adding a test case for impersonating users would be beneficial.


Verdict: Approve

This is a clean, well-implemented change that follows existing patterns in the codebase. The security model is appropriate - impersonating users are trusted support/admin personnel who need query access to debug customer issues.

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: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)

77-109: Authorization is actually mitigated by downstream membership enforcement, but the design is fragile and confusing.

The early return if (isAdmin || isImpersonating) return true; bypasses the org membership check within hasQueryAccess, but only the admin's ID is passed downstream. findProjectBySlug still enforces membership validation: members: { some: { userId } } where userId is the admin's ID. This means an admin cannot access orgs they don't belong to, even while impersonating.

However, this is a poor design pattern because security is achieved incidentally through downstream enforcement rather than explicit gates. The code is misleading—readers see an unconditional access grant and must trace multiple functions to verify the actual authorization.

The proposed adjustment is still worthwhile: move the impersonation bypass to after the membership check rather than before it, making the security logic explicit and not reliant on downstream functions being correct.

🧹 Nitpick comments (1)
apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx (1)

117-124: Good propagation of user.isImpersonating; consider an args object to avoid boolean-parameter order bugs.

Now that hasQueryAccess takes multiple booleans, passing an object (e.g. { userId, isAdmin, isImpersonating, organizationSlug }) would make call sites self-documenting and reduce accidental arg swapping.

Also applies to: 158-168

📜 Review details

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 42dfb87 and 9730cae.

📒 Files selected for processing (2)
  • apps/webapp/app/components/navigation/SideMenu.tsx
  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

**/*.{ts,tsx}: Use types over interfaces for TypeScript
Avoid using enums; prefer string unions or const objects instead

Files:

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
{packages/core,apps/webapp}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use zod for validation in packages/core and apps/webapp

Files:

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (.github/copilot-instructions.md)

Use function declarations instead of default exports

Files:

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
apps/webapp/app/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

Access all environment variables through the env export of env.server.ts instead of directly accessing process.env in the Trigger.dev webapp

Files:

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
apps/webapp/**/*.{ts,tsx}

📄 CodeRabbit inference engine (.cursor/rules/webapp.mdc)

apps/webapp/**/*.{ts,tsx}: When importing from @trigger.dev/core in the webapp, use subpath exports from the package.json instead of importing from the root path
Follow the Remix 2.1.0 and Express server conventions when updating the main trigger.dev webapp

Files:

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
**/*.{js,ts,jsx,tsx,json,md,css,scss}

📄 CodeRabbit inference engine (AGENTS.md)

Format code using Prettier

Files:

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
  • apps/webapp/app/components/navigation/SideMenu.tsx
🧠 Learnings (1)
📚 Learning: 2025-12-08T15:19:56.823Z
Learnt from: 0ski
Repo: triggerdotdev/trigger.dev PR: 2760
File: apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx:278-281
Timestamp: 2025-12-08T15:19:56.823Z
Learning: In apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.runs.$runParam/route.tsx, the tableState search parameter uses intentional double-encoding: the parameter value contains a URL-encoded URLSearchParams string, so decodeURIComponent(value("tableState") ?? "") is required to fully decode it before parsing with new URLSearchParams(). This pattern allows bundling multiple filter/pagination params as a single search parameter.

Applied to files:

  • apps/webapp/app/routes/_app.orgs.$organizationSlug.projects.$projectParam.env.$envParam.query/route.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (24)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (6, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (4, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (3, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (2, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (6, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (7, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (8, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (5, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (7, 8)
  • GitHub Check: units / internal / 🧪 Unit Tests: Internal (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (1, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (8, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (2, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (4, 8)
  • GitHub Check: units / webapp / 🧪 Unit Tests: Webapp (3, 8)
  • GitHub Check: units / packages / 🧪 Unit Tests: Packages (1, 1)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - npm)
  • GitHub Check: typecheck / typecheck
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (ubuntu-latest - pnpm)
  • GitHub Check: e2e / 🧪 CLI v3 tests (windows-latest - npm)
  • GitHub Check: claude-review
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (1)
apps/webapp/app/components/navigation/SideMenu.tsx (1)

277-286: Query menu visibility change looks correct; confirm user.admin vs isAdmin intent.

Including user.isImpersonating aligns the menu with the route-level access change. One small consistency check: the header area uses isAdmin (from useHasAdminAccess()), but Query uses user.admin. If that split is intentional (e.g., user.admin reflects the impersonated user), consider a short inline comment to prevent future “cleanup” regressions.

@matt-aitken matt-aitken merged commit 839d5e8 into main Jan 9, 2026
30 checks passed
@matt-aitken matt-aitken deleted the query-access branch January 9, 2026 14:57
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.

3 participants