Skip to content

fix: LiveQuery role cache is not invalidated for all users affected by a role write or delete - #10629

Open
AdrianCurtin wants to merge 1 commit into
parse-community:alphafrom
AdrianCurtin:fix_livequery_role_cache_broadcast
Open

AdrianCurtin wants to merge 1 commit into
parse-community:alphafrom
AdrianCurtin:fix_livequery_role_cache_broadcast

Conversation

@AdrianCurtin

@AdrianCurtin AdrianCurtin commented Aug 13, 2026 •

Copy link
Copy Markdown

Pull Request

Issue

Closes #10628.

LiveQueryController.clearCachedRoles(user) invalidated the LiveQuery server's cached auth for one user, the actor on the request, and only when there was one. Two cases were never invalidated:

  • No user on the request. The method returned early when user was falsy, so a master key role write or delete published nothing at all. Managing roles with the master key, from admin tooling or cloud code, is the common case.
  • Users other than the actor. The publisher sent a single { userId } and ParseLiveQueryServer#_clearCachedRoles resolved _Session rows for that one user. A role write changes the effective closure of every member of the role and of any role inheriting from it. Adding a member is the clearest example: the actor is the admin doing the write, the affected user is the member being added, and only the actor was invalidated.

Until its authCache entry expired on cacheTimeout, a subscriber kept receiving events decided from a stale role closure.

Approach

clearCache messages now carry clearAll: true, and a LiveQuery server receiving one drops its whole authCache rather than one user's sessions. Entries are repopulated lazily by getAuthForSessionToken, so the cost is a re-resolution per active session after a role write, and role writes are rare relative to events.

Three details worth reviewer attention:

  • userId is still published when it is known. A LiveQuery server on an older version ignores clearAll and reads userId, so it keeps doing exactly what it does today rather than silently doing nothing. Mixed-version deployments degrade to current behavior instead of breaking.
  • _clearCachedRoles(userId) is kept for the reverse direction, an older Parse Server publishing { userId } to a LiveQuery server on this version.
  • A standalone LiveQuery server clears its own role cache. It runs in its own process with its own cache controller, which the publishing Parse Server's cacheController.role.clear() never touched. Failures there are caught and logged rather than propagated, matching _clearCachedRoles.

The whole cache is cleared rather than a computed set of affected sessions because the affected set cannot be reconstructed for a delete: by the time the message is published, the _Role row and its _Join rows are gone. Snapshotting members before the destroy would put the cost on every delete and still miss transitive members.

Tests

spec/ParseLiveQueryServer.spec.js gains a role cache invalidation block:

  • A role change with no acting user publishes clearAll, which is the master key case that previously published nothing.
  • A role change with an acting user still publishes userId alongside clearAll, pinning the back compat contract.
  • A clearAll message routes to the full clear, and a message without it routes to the targeted clear.
  • A full clear empties authCache and clears the role cache.
  • A full clear resolves rather than rejecting when the role cache is unavailable.

spec/ParseLiveQueryServer.spec.js, spec/ParseLiveQuery.spec.js, spec/ParseRole.spec.js, spec/Auth.spec.js and spec/rest.spec.js all pass against MongoDB 8.

Tasks

  • Add tests
  • Add changes to documentation (code comments)

Summary by CodeRabbit

  • Bug Fixes
    • LiveQuery authorization caches are now invalidated when role changes occur, including changes made without an acting user.
    • Full cache clears now clear both authorization data and role-cache data when available.
    • A failure while clearing the role cache no longer prevents the full-clear operation from completing.
    • Targeted role-cache invalidation for a specific user continues to be supported.

@parse-github-assistant

Copy link
Copy Markdown

🚀 Thanks for opening this pull request! We appreciate your effort in improving the project. Please let us know once your pull request is ready for review.

Tip

  • Keep pull requests small. Large PRs will be rejected. Break complex features into smaller, incremental PRs.
  • Use Test Driven Development. Write failing tests before implementing functionality. Ensure tests pass.
  • Group code into logical blocks. Add a short comment before each block to explain its purpose.
  • We offer conceptual guidance. Coding is up to you. PRs must be merge-ready for human review.
  • Our review focuses on concept, not quality. PRs with code issues will be rejected. Use an AI agent.
  • Human review time is precious. Avoid review ping-pong. Inspect and test your AI-generated code.

Note

Please respond to review comments from AI agents just like you would to comments from a human reviewer. Let the reviewer resolve their own comments, unless they have reviewed and accepted your commit, or agreed with your explanation for why the feedback was incorrect.

Caution

Pull requests must be written using an AI agent with human supervision. Pull requests written entirely by a human will likely be rejected, because of lower code quality, higher review effort and the higher risk of introducing bugs. Please note that AI review comments on this pull request alone do not satisfy this requirement. Our CI and AI review are safeguards, not development tools. If many issues are flagged, rethink your development approach. Invest more effort in planning and design rather than using review cycles to fix low-quality code.

@coderabbitai

coderabbitai Bot commented Aug 13, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Organization UI
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 5d5646f4-856c-495b-a0e8-8209c9ab18be
📥 Commits

Reviewing files that changed from the base of the PR and between 23c8c89 and a946ab6.

📒 Files selected for processing (2)
  • spec/ParseLiveQueryServer.spec.js
  • src/LiveQuery/ParseLiveQueryServer.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 8 remain after this review.


📝 Walkthrough

Walkthrough

Role changes now publish LiveQuery cache-invalidation messages even when no acting user is present. The server processes global invalidation messages by clearing its authorization cache and, when available, its role cache. Messages without the global-clear flag retain targeted invalidation.

Changes

LiveQuery role-cache invalidation

Layer / File(s) Summary
Publish role-cache invalidation
src/Controllers/LiveQueryController.js, src/LiveQuery/ParseCloudCodePublisher.js
Role changes publish invalidation messages without requiring a user. Messages include clearAll: true and include userId when a user is provided.
Process and test cache clearing
src/LiveQuery/ParseLiveQueryServer.ts, spec/ParseLiveQueryServer.spec.js
The server clears all authorization and role caches for global invalidation messages. Messages without clearAll retain targeted clearing by user ID. Tests cover publication, dispatch, cache clearing, and rejected role-cache clears.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~15 minutes

Severity of issue fixed: Medium

Suggested reviewers: mtrezza

🚥 Pre-merge checks | ✅ 7
✅ Passed checks (7 passed)
Check name Status Explanation
Title check ✅ Passed The title starts with the required fix: prefix and clearly describes the LiveQuery role-cache invalidation change.
Description check ✅ Passed The description includes the required Pull Request, Issue, Approach, and Tasks sections. It explains the issue, the implementation, compatibility behavior, and tests. The listed tests and documentatio…
Linked Issues check ✅ Passed Issue #10628 requires LiveQuery authorization to refresh for all sessions affected by role writes or deletes, including master-key requests without an acting user. clearCachedRoles now publishes wit…
Out of Scope Changes check ✅ Passed The changes are limited to role-cache invalidation and its tests. The added cache clearing, compatibility handling, comments, and tests all support issue #10628. No unrelated change is present in the …
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 2…
Security Check ✅ Passed The diff adds an internal clearCache pub/sub signal and clears LiveQuery auth and role caches. This removes cached authorization state; it does not grant access or bypass authorization. The message …
Engage In Review Feedback ✅ Passed No review feedback required engagement. The supplied review context reports no posted CodeRabbit threads and zero actionable findings in the current review.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

Comment @coderabbitai help to get the list of available commands.

@AdrianCurtin AdrianCurtin changed the title fix: LiveQuery role cache is not invalidated for all users affected b… fix: LiveQuery role cache is not invalidated for all users affected by a role write or delete Aug 13, 2026
@AdrianCurtin
AdrianCurtin force-pushed the fix_livequery_role_cache_broadcast branch from 23c8c89 to a946ab6 Compare October 6, 2026 12:08

This branch has not been deployed

No deployments
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.

LiveQuery role cache is not invalidated for all users affected by a role write or delete

1 participant