Skip to content

Include team websites for all team roles in the Websites list - #4539

Open
yolk3d wants to merge 1 commit into
umami-software:devfrom
yolk3d:team-websites-list
Open

yolk3d wants to merge 1 commit into
umami-software:devfrom
yolk3d:team-websites-list

Conversation

@yolk3d

@yolk3d yolk3d commented Sep 15, 2026

Copy link
Copy Markdown

Why

I run Umami for several sites that belong to teams, and each client is a view-only member of their own team. They can open their site, but when they sign in the Websites page is empty, because it only lists websites they own. Team owners have the same gap: team sites only appear after switching to that team.

What changed

  • includeTeams now follows the same rule as canViewWebsite: websites the user owns, plus websites with no owner in any team they belong to, at any role. Before, it only matched team-owner and team-manager, and it also listed team websites that still had an owner, which those members can't open.
  • The Websites page passes includeTeams when no team is selected. Team views are unchanged, and so is the API default without includeTeams.
  • The edit button is hidden on rows the user can't update, such as a site they only view through a team.
  • Updated the includeTeams description and regenerated the API client.

Related to #4052. The concern there was that account and team context don't mix anywhere yet. This leaves the API default alone and only mixes them on the personal Websites list.

Testing

  • New API tests: a team-view-only member sees their team's website on /api/websites, /api/me/websites and /api/users/{userId}/websites with includeTeams. They don't see another team's website or websites owned by other users, the default list is unchanged, the list agrees with GET /api/websites/{websiteId}, and the website drops off once they leave the team.
  • A unit test pins the query, including userId: null. A website with both userId and teamId set can't be created through the API, so that case is only covered there.
  • pnpm test:api:run against the test compose stack: Postgres 276 passed, ClickHouse 275 passed and 1 skipped (session deletion). Both full runs also end with a tokens fixture teardown timeout outside any test. It happened too in a run where the new tests failed before sending a request, and not in a single-spec run, so I don't think it comes from this change, but I haven't checked it against a clean dev.
  • pnpm build passes. pnpm lint and tsc report errors that already exist on dev, none in files changed here.

View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.

includeTeams now matches canViewWebsite: websites the user owns, plus
websites with no owner in any team the user belongs to, at any role.
The Websites page passes it when no team is selected, and hides the
edit action on rows the user cannot update.
@vercel

vercel Bot commented Sep 15, 2026

Copy link
Copy Markdown

@yolk3d is attempting to deploy a commit to the Umami Software Team on Vercel.

A member of the Team first needs to authorize it.

@greptile-apps

greptile-apps Bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR includes unowned team websites in a user’s personal website list for every team membership role while preserving the API’s default behavior.

  • Aligns team-inclusive listing with website-view authorization.
  • Requests team-inclusive results only when no specific team is selected.
  • Includes the caller’s team role and suppresses edit actions when that role lacks update permission.
  • Adds query-level and API coverage for view-only membership, isolation, defaults, and membership removal.

Confidence Score: 5/5

The PR appears safe to merge; no actionable correctness, security, or repository-rule issues were identified.

The team-inclusive query remains scoped to the authenticated or administratively authorized target user, matches existing view authorization, and supplies the membership data required for row-level edit gating.

Important Files Changed

Filename Overview
src/queries/prisma/website.ts Broadens team-inclusive listing to all memberships while restricting team matches to unowned websites and returning the caller’s role.
src/app/(main)/websites/WebsitesPage.tsx Enables team-inclusive results only for the personal Websites view.
src/app/(main)/websites/WebsitesDataTable.tsx Propagates the optional includeTeams request parameter through the existing query hook.
src/app/(main)/websites/WebsitesTable.tsx Applies row-level update permission checks before rendering the settings action.
tests/api/websites.spec.ts Covers team-view-only visibility, endpoint consistency, isolation, unchanged defaults, and membership removal.
src/queries/prisma/website.test.ts Pins the ownership and team-membership query structure, including the required null user owner condition.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Websites page] --> B{Team selected?}
    B -->|Yes| C[Request selected team's websites]
    B -->|No| D[Request user websites with includeTeams]
    D --> E[Owned websites]
    D --> F[Unowned websites in teams where user is a member]
    E --> G[Combined paginated list]
    F --> G
    G --> H{Caller can update row?}
    H -->|Owner or permitted team role| I[Show edit action]
    H -->|View-only team role| J[Hide edit action]
Loading

Reviews (1): Last reviewed commit: "Include team websites for all team roles..." | Re-trigger Greptile

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.

1 participant