Skip to content

Fix pat and queries#735

Merged
feruzm merged 2 commits into
developfrom
matter
Apr 2, 2026
Merged

Fix pat and queries#735
feruzm merged 2 commits into
developfrom
matter

Conversation

@feruzm
Copy link
Copy Markdown
Member

@feruzm feruzm commented Apr 2, 2026

Summary by CodeRabbit

Bug Fixes

  • Resolved subscription data caching issue where stale information could persist across requests and incorrectly affect channel auto-joining decisions
  • Default Mattermost team channels (town-square and off-topic) are now properly excluded from displayed channel lists
  • Enhanced personal access token validation and storage using more efficient authentication verification mechanisms

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 2, 2026

Warning

Rate limit exceeded

@feruzm has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 16 minutes and 13 seconds before requesting another review.

Your organization is not enrolled in usage-based pricing. Contact your admin to enable usage-based pricing to continue reviews beyond the rate limit, or try again in 16 minutes and 13 seconds.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: e418e5c5-323d-4b56-8408-0c20af9c9153

📥 Commits

Reviewing files that changed from the base of the PR and between 3bee188 and 7bf3d24.

📒 Files selected for processing (3)
  • apps/web/src/server/mattermost.ts
  • apps/web/src/specs/api/mattermost-bootstrap-subscriptions.spec.ts
  • apps/web/src/specs/api/mattermost-default-channels-filter.spec.ts
📝 Walkthrough

Walkthrough

These changes refactor Mattermost integration logic across three files: replacing shared query client with instance-scoped client to prevent stale subscription data in bootstrap handler, filtering default channels (town-square, off-topic) from channel responses, and restructuring personal access token management to store and validate tokens via user props.

Changes

Cohort / File(s) Summary
Bootstrap Route Handler
apps/web/src/app/api/mattermost/bootstrap/route.ts
Replaced shared getQueryClient() with instance-scoped QueryClient in POST handler to prevent stale subscription data across requests; added comments explaining why React cache() is inappropriate for route handlers.
Channels Route Handler
apps/web/src/app/api/mattermost/channels/route.ts
Added MATTERMOST_DEFAULT_CHANNELS set containing "town-square" and "off-topic"; new filter excludes these Mattermost default channels from response across all code paths.
Mattermost Server Utilities
apps/web/src/server/mattermost.ts
Added CHAT_PAT_PROP constant; replaced getExistingToken() with isTokenValid() using /users/me validation; updated createToken() to store PAT secret in user props; refactored ensurePersonalToken() to retrieve and validate stored token before fallback creation.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

  • Improve chats #628: Modifies the same Mattermost route handlers (bootstrap and channels) with overlapping changes to bootstrap and channel handling logic.
  • Improve account update and chat cleanup #676: Overlapping code-level modifications to bootstrap route handler and server-side Mattermost token/user management with related POST handler logic.
  • Simplify video uploading #731: Builds upon the channels and server helpers introduced in these changes, using the refactored channel retrieval and removal utilities.

Suggested labels

patch

Poem

🐰 With query clients scoped and tokens stored with care,
Default channels filtered from the Mattermost air,
Personal access tokens validated anew,
Stale subscriptions banished—this update shines true! 🌟

🚥 Pre-merge checks | ✅ 1 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 16.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Fix pat and queries' is vague and uses non-descriptive abbreviations that don't clearly convey the actual changes made to the codebase. Use a more descriptive title that clearly explains the main change, such as 'Store and validate Mattermost PAT in user props and fix subscription query caching' or 'Fix Mattermost token validation and subscription query handling'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch matter

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.

Copy link
Copy Markdown
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: 4

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

Inline comments:
In `@apps/web/src/app/api/mattermost/bootstrap/route.ts`:
- Around line 86-97: Add a regression test that verifies per-request
subscription reads don't reuse cached data: simulate two consecutive POST
bootstrap requests that return different subscription fixtures and assert the
second request does not auto-join communities from the first response.
Specifically, in test setup target the bootstrap route logic that constructs a
new QueryClient (symbol: QueryClient) and calls fetchQuery with
getAccountSubscriptionsQueryOptions(username), and ensure the test uses distinct
mock responses for those calls so the subscriptions variable (Subscription[]) is
refreshed per-request; fail the test if stale subscription data from the first
call causes auto-joining on the second.

In `@apps/web/src/app/api/mattermost/channels/route.ts`:
- Around line 111-119: Add a regression test that ensures
MATTERMOST_DEFAULT_CHANNELS filtering doesn't break default-channel selection:
craft a payload with channels including "town-square" and "off-topic" plus a
real channel, run the same code path that computes hasCategories and
filteredChannels (referencing MATTERMOST_DEFAULT_CHANNELS, hasCategories,
filteredChannels) and assert the chats-page-client's defaultChannelId resolution
still picks the intended non-default channel; add this test alongside the
chats-page-client tests and ensure it fails if the default channels are not
removed from the payload.

In `@apps/web/src/server/mattermost.ts`:
- Around line 280-291: isTokenValid currently treats every exception as an
invalid token and ensurePersonalToken swallows all getMattermostUserWithProps
failures, causing createToken to run on transient 5xx/network errors; change
both places to only treat 401/403 (or explicit auth error from
mmFetch/getMattermostUserWithProps) as “invalid” and proceed to create a new
PAT, but rethrow other errors so they surface (returning 502 upstream).
Concretely, in isTokenValid(token) inspect the caught error for an HTTP status
(e.g., err.status or err.response?.status) and return false only for 401/403,
otherwise rethrow; similarly in ensurePersonalToken when calling
getMattermostUserWithProps, check the error status and only call createToken()
on auth errors, otherwise propagate the error.
- Around line 295-307: The patch currently overwrites the user's props by
sending a single-key props object when calling mmFetch(`/users/${userId}/patch`)
to store result.token under CHAT_PAT_PROP, which can clobber existing props;
instead, fetch or use the existing props and merge the new key into them before
PATCHing. Update the code around mmFetch(`/users/${userId}/patch`) to read the
current user props (or use the same merge pattern used elsewhere in this
module), create a new props object that copies existing props and sets
[CHAT_PAT_PROP]: result.token, and send that merged props in the body so
existing fields like ecency_left_channels, DM privacy, and bans are preserved.
🪄 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: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9da7771b-adbb-48b4-84dd-dfccbfc6e1c3

📥 Commits

Reviewing files that changed from the base of the PR and between 1012aff and 3bee188.

📒 Files selected for processing (3)
  • apps/web/src/app/api/mattermost/bootstrap/route.ts
  • apps/web/src/app/api/mattermost/channels/route.ts
  • apps/web/src/server/mattermost.ts

Comment on lines +86 to 97
// 4) Hive subscriptions — use a per-request QueryClient.
// Do NOT use the shared getQueryClient() here: React's cache() is
// scoped to Server Components, not Route Handlers. In a long-lived
// container the shared QueryClient persists across requests, serving
// stale subscription data that causes auto-joining to unsubscribed communities.
let subscriptions: Subscription[] = [];
try {
const qc = new QueryClient();
subscriptions =
(await getQueryClient().fetchQuery(
(await qc.fetchQuery(
getAccountSubscriptionsQueryOptions(username)
)) || [];
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.

🛠️ Refactor suggestion | 🟠 Major

Add a regression test for per-request subscription reads.

Auto-join decisions now depend on fetching subscriptions fresh for each bootstrap. Please add coverage that two consecutive POST calls with different subscription fixtures don't reuse the previous response and join stale communities. As per coding guidelines, All new features in @ecency/web require tests.

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

In `@apps/web/src/app/api/mattermost/bootstrap/route.ts` around lines 86 - 97, Add
a regression test that verifies per-request subscription reads don't reuse
cached data: simulate two consecutive POST bootstrap requests that return
different subscription fixtures and assert the second request does not auto-join
communities from the first response. Specifically, in test setup target the
bootstrap route logic that constructs a new QueryClient (symbol: QueryClient)
and calls fetchQuery with getAccountSubscriptionsQueryOptions(username), and
ensure the test uses distinct mock responses for those calls so the
subscriptions variable (Subscription[]) is refreshed per-request; fail the test
if stale subscription data from the first call causes auto-joining on the
second.

Comment on lines +111 to +119
// Mattermost auto-joins users to these default channels when they join
// the team. Hide them since no Hive user intentionally joined these.
const MATTERMOST_DEFAULT_CHANNELS = new Set(["town-square", "off-topic"]);

const hasCategories = (categoriesResponse.categories || []).length > 0;
const filteredChannels = channels.filter((channel) => {
// Filter out Mattermost team default channels
if (MATTERMOST_DEFAULT_CHANNELS.has(channel.name)) return false;

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.

🛠️ Refactor suggestion | 🟠 Major

Add regression coverage for the default-channel filter.

apps/web/src/app/chats/_components/chats-page-client.tsx:16-25 derives defaultChannelId from this payload. Please add a test proving that removing "town-square" and "off-topic" still supports the default-channel selection flow expected by the chats page. As per coding guidelines, All new features in @ecency/web require tests.

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

In `@apps/web/src/app/api/mattermost/channels/route.ts` around lines 111 - 119,
Add a regression test that ensures MATTERMOST_DEFAULT_CHANNELS filtering doesn't
break default-channel selection: craft a payload with channels including
"town-square" and "off-topic" plus a real channel, run the same code path that
computes hasCategories and filteredChannels (referencing
MATTERMOST_DEFAULT_CHANNELS, hasCategories, filteredChannels) and assert the
chats-page-client's defaultChannelId resolution still picks the intended
non-default channel; add this test alongside the chats-page-client tests and
ensure it fails if the default channels are not removed from the payload.

Comment thread apps/web/src/server/mattermost.ts
Comment thread apps/web/src/server/mattermost.ts
@feruzm feruzm merged commit 4d6dbbd into develop Apr 2, 2026
@feruzm feruzm deleted the matter branch April 2, 2026 10:24
This was referenced Apr 6, 2026
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