Fix wrong current user in FW Lite comments for cross-server projects - #2490
Fix wrong current user in FW Lite comments for cross-server projects#2490myieye wants to merge 9 commits into
Conversation
Opening a project from the home page could show the wrong current user in the comments UI: Edit buttons on other people's comments, hidden on your own, and new comments authored as the wrong user. Root cause: ProjectData.LastUserId was written by two flows with different scoping. The home page enumerates every logged-in server and, matching local projects by GUID alone, stamped each server's user onto them - so a project downloaded from one server got clobbered with another server's user when both list the same GUID (shared history). That also authored CRDT commits as the wrong user until the next sync. - Scope the write to the project's origin server in CombinedProjectsService. - Resolve the origin user from the auth cache at project open, before the UI reads identity, so it is right from the first render (falls back to the persisted value when offline/signed out). - Rename LastUser* -> OriginUser* to reflect the single origin-user meaning and single write path; DB columns keep their names, so no migration. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZEJ549cwaz1uHfq7EKyPu
ExecuteSync refreshes the origin user (UpdateOriginUser) after capturing the ProjectData record, so passing the captured record's user id to ApplySyncedCommentReadStatus used a stale/missing id. Use the just-fetched currentUser id instead, so read status is attributed to the right user right after coming back online or switching accounts. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZEJ549cwaz1uHfq7EKyPu
If GetCurrentUser returns null on a transient token refresh (the user is still signed in, so UpdateOriginUser keeps the persisted identity), passing that null straight to ApplySyncedCommentReadStatus marks every synced comment unread. Fall back to the persisted OriginUserId so read status stays attributed to the last-known user. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZEJ549cwaz1uHfq7EKyPu
Per review: LastUserId/LastUserName are the honest names — the value is the last signed-in user we saw and is overwritten on the next open/sync (e.g. an account switch), so "OriginUser" over-claimed a canonical per-project user. The origin scoping that fixes the bug lives in the CombinedProjectsService gate, not the field name, so the rename bought nothing and cost clarity. Reverts the property/method rename, the HasColumnName mapping, the generated TS, and the verified snapshot back to develop, and restores the staleness todo in NewMetadata (reworded: now stale only until the next open or sync, since identity is resolved at open). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZEJ549cwaz1uHfq7EKyPu
Opening a project resolved the origin user via GetCurrentUser, which goes through GetAuth and can trigger a silent token refresh (a network round-trip) when the cached token is near/after expiry. We only need who the user is here, not a usable token, so read the account straight from the local MSAL cache instead. Adds OAuthClient.GetCachedUser (a sibling of IsSignedIn: cache-only, no network) and uses it at project open, keeping OpenCrdtProject off the network. The token refresh still happens in the background sync, where latency doesn't matter. Also corrects the now-accurate "no network" comment. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZEJ549cwaz1uHfq7EKyPu
Drops the reword so the comment is unchanged from develop (no diff there). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ZEJ549cwaz1uHfq7EKyPu
Drop em-dashes and de-duplicate the cached-read rationale that now lives on GetCachedUser's docstring. No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📝 WalkthroughWalkthroughChangesIdentity and project state
Estimated code review effort: 3 (Moderate) | ~20 minutes Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
|
The latest updates on your projects. Learn more about Argos notifications ↗︎
|
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@backend/FwLite/FwLiteShared/Auth/OAuthClient.cs`:
- Around line 201-205: Update GetCachedUser() to select the cached MSAL account
whose HomeAccountId.Environment matches the configured project origin server or
authority, instead of using FirstOrDefault() across all accounts. Preserve the
existing null handling and LexboxUser construction after selecting the matching
account.
In `@backend/FwLite/FwLiteShared/Services/ProjectServicesProvider.cs`:
- Around line 87-100: The ResolveOriginUser method must tolerate expected MSAL
cache/account-read failures from GetCachedUser so OpenCrdtProject can still
create the project scope. Catch the relevant exception around the cached-user
lookup, return the original projectData unchanged on failure, and add coverage
for this failure path while preserving the existing null-user behavior.
🪄 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: Repository UI
Review profile: CHILL
Plan: Pro Plus
Run ID: e9294d87-7d22-4c37-a7ed-29e2be2c38c5
📒 Files selected for processing (7)
backend/FwLite/FwLiteShared.Tests/Auth/OAuthClientIsSignedInTests.csbackend/FwLite/FwLiteShared.Tests/Projects/CombinedProjectsServiceTests.csbackend/FwLite/FwLiteShared/Auth/OAuthClient.csbackend/FwLite/FwLiteShared/Projects/CombinedProjectsService.csbackend/FwLite/FwLiteShared/Services/ProjectServicesProvider.csbackend/FwLite/FwLiteShared/Sync/SyncService.csbackend/FwLite/LcmCrdt.Tests/CurrentProjectServiceTests.cs
GetAccountsAsync filters by the app's OIDC authority, so the per-server client only sees that server's accounts (addresses the FirstOrDefault cross-server concern). No behavior change. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
GetCachedUser reads the MSAL cache on the synchronous open path, so a cache-read failure would fail OpenCrdtProject. Wrap it: log and keep the persisted origin user, matching the existing signed-out fallback. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
[Claude, autonomous]
Resolves #2491
Fixes the wrong current user in FW Lite comments when a project's GUID exists on more than one logged-in server (e.g. Sena 3 downloaded from staging but also present on dev): FW Lite offered Edit on other users' comments, hid it on your own, and authored new comments as the wrong user. The same field also drove wrong CRDT commit authorship.
Root cause:
ProjectData.LastUserIdwas written unscoped. Loading the home page enumerates every logged-in server and stamped each server's user onto local projects matched by GUID alone, clobbering the origin server's user.CombinedProjectsService: a server only stamps its user/role on projects whose origin is that server.