Skip to content

Add Support for Switching Between User Teams with Cookie-Based Context #134

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

marconneves
Copy link

@marconneves marconneves commented Mar 27, 2025

This PR introduces a feature to allow users to switch between their associated teams dynamically, addressing the current limitation where the application supports only a single team context. The goal is to enhance flexibility for users who belong to multiple teams, enabling seamless transitions without requiring logout/login cycles.

Internally, I’ve successfully implemented this approach for my company to separate two projects that required distinct logs and operators. As an admin, I previously had to log out and log back in to switch contexts, which was inefficient. This proposal draws inspiration from that experience and aims to bring a similar capability to the platform.

Proposed Behavior

  • Team Selection: When a user selects a team, a unsendTeamId cookie is set to persist the choice. This cookie is accessible server-side via tRPC middleware.
  • Context Switch: The application context updates to reflect the selected team, ensuring all subsequent operations (queries, mutations, etc.) operate within the chosen team’s scope.
  • Cache Management: After switching teams, the React Query cache is cleared to prevent stale data from the previous team context affecting the new one.

Implementation Details

  • Frontend: The TeamProvider now persists the selected team in a cookie using js-cookie and updates the current team state. (See previous commits for the client-side changes.)
  • Backend: The teamProcedure middleware in tRPC reads the unsendTeamId cookie via next/headers and filters the user’s teams to set the appropriate context. If the cookie is invalid or absent, it falls back to the user’s first team.
  • Fallback Logic: If no valid team is found matching the cookie, the system defaults to the user’s first available team to ensure a smooth experience.

Why This Matters

This feature eliminates the need for repeated logins when managing multiple teams, which is particularly useful for admins or users with cross-team responsibilities. It aligns with real-world use cases (like my internal project separation) and could be a valuable addition for multi-team workflows.

Questions for Reviewers

  • What do you think of this approach? Does it align with the platform’s direction?
  • Could this be a feature worth expanding into an official multi-team support capability?
  • Are there any edge cases or security concerns I should address (e.g., cookie tampering, team access validation)?

Next Steps

  • Test the feature across different user roles (admin, member) and team configurations.
  • Gather feedback on UX implications of team switching.
  • Consider additional optimizations, like preserving some cache data selectively instead of a full clear.

Looking forward to your thoughts!

image

@marconneves
Copy link
Author

@KMKoushik I create this propose, what do you think?

@KMKoushik KMKoushik requested review from Copilot and KMKoushik March 29, 2025 03:41
Copy link

@Copilot 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

This PR adds support for dynamically switching between user teams via a cookie-based context, eliminating the need for repeated logins when managing multiple teams. Key changes include:

  • Server-side cookie retrieval and team validation in the tRPC middleware.
  • Enhancements to the team context provider to update the current team based on a cookie, with React Query cache resets.
  • Addition of a UI component that enables team selection in the dashboard.

Reviewed Changes

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

File Description
apps/web/src/server/api/trpc.ts Implements cookie-based team selection logic via tRPC middleware.
apps/web/src/providers/team-context.tsx Updates team state from the cookie and resets queries on team change.
apps/web/src/app/(dashboard)/nav-button.tsx Introduces a team selection UI component using Select from @unsend/ui.
apps/web/src/app/(dashboard)/dasboard-layout.tsx Integrates the new ChangeTeam component into the dashboard navigation.
Files not reviewed (2)
  • apps/web/package.json: Language not supported
  • pnpm-lock.yaml: Language not supported
Comments suppressed due to low confidence (3)

apps/web/src/server/api/trpc.ts:116

  • Consider validating that the cookie value is a proper numeric string before parsing it. This will help avoid issues if a non-numeric value is provided, which may lead to unexpected fallback behavior.
const currentTeamId = cookieStore.get("unsendTeamId")?.value ? parseInt(cookieStore.get("unsendTeamId")!.value, 10) : null;

apps/web/src/providers/team-context.tsx:43

  • Double-check that the specified cookie options (path and sameSite) align with the server-side cookie retrieval method to ensure consistent behavior across client and server.
Cookies.set('unsendTeamId', String(teamId), { expires: 7, path: "/", sameSite: "lax"  })

apps/web/src/app/(dashboard)/nav-button.tsx:63

  • Ensure that defaulting to 0 as a team ID when no team is available does not lead to unintended behavior in the selection UI, especially if 0 is not a valid team identifier.
value={String(currentTeam?.id || teams[0]?.id || 0)}

function selectTeam(teamId: number){
const teamFounded = teams?.find(team => team.id === teamId);

Cookies.set('unsendTeamId', String(teamId), { expires: 7, path: "/", sameSite: "lax" })
Copy link
Member

Choose a reason for hiding this comment

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

tbh, this should not be a browser side thing, should send a request to be and it should verify team and roles etc and set it as http secure cookie

@KMKoushik
Copy link
Member

this seems to be a good idea and db schema already supports this. need lot's of testing though and also needs some business pov as well. ie) i don't want people to create infinite free accounts etc.

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