Skip to content

Fix wrong current user in FW Lite comments for cross-server projects - #2490

Open
myieye wants to merge 9 commits into
developfrom
claude/fw-lite-user-identity-bug-iozg90
Open

Fix wrong current user in FW Lite comments for cross-server projects#2490
myieye wants to merge 9 commits into
developfrom
claude/fw-lite-user-identity-bug-iozg90

Conversation

@myieye

@myieye myieye commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

[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.LastUserId was 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.

  • Origin-scope the write in CombinedProjectsService: a server only stamps its user/role on projects whose origin is that server.
  • Resolve the origin user from the local MSAL cache at project open (no token, no network) so identity is right from the first render; fall back to the persisted value when signed out.
  • Attribute synced comment read-status to the freshly resolved user.

claude and others added 7 commits July 27, 2026 17:25
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>
@github-actions github-actions Bot added the 💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related label Jul 27, 2026
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Identity and project state

Layer / File(s) Summary
Cached identity persistence
backend/FwLite/FwLiteShared/Auth/OAuthClient.cs, backend/FwLite/FwLiteShared/Services/ProjectServicesProvider.cs, backend/FwLite/LcmCrdt.Tests/CurrentProjectServiceTests.cs, backend/FwLite/FwLiteShared.Tests/Auth/OAuthClientIsSignedInTests.cs, backend/FwLite/FwLiteShared/Sync/SyncService.cs
Adds local cached-user resolution, persists origin-server identity during project opening, tests last-user updates, and uses the authenticated user for sync read-status updates.
Server-origin ownership checks
backend/FwLite/FwLiteShared/Projects/CombinedProjectsService.cs, backend/FwLite/FwLiteShared.Tests/Projects/CombinedProjectsServiceTests.cs
Restricts project server-information updates to projects whose stored origin server matches the queried server, with matching and non-matching ownership tests.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Suggested reviewers: hahn-kev

Poem

I’m a bunny with cached names,
Stamping projects with rightful claims.
Origin servers guard the door,
Sync remembers who logged before.
Tests hop happily—boing, boing!

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title clearly matches the main fix: correcting the current user for cross-server FW Lite comments.
Description check ✅ Passed The description directly explains the bug, root cause, and the implemented fixes reflected in the changeset.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/fw-lite-user-identity-bug-iozg90

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.

@argos-ci

argos-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Jul 27, 2026, 4:00 PM
e2e (Inspect) ✅ No changes detected - Jul 27, 2026, 4:07 PM

@coderabbitai coderabbitai Bot left a comment

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.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 819ae99 and 05fe964.

📒 Files selected for processing (7)
  • backend/FwLite/FwLiteShared.Tests/Auth/OAuthClientIsSignedInTests.cs
  • backend/FwLite/FwLiteShared.Tests/Projects/CombinedProjectsServiceTests.cs
  • backend/FwLite/FwLiteShared/Auth/OAuthClient.cs
  • backend/FwLite/FwLiteShared/Projects/CombinedProjectsService.cs
  • backend/FwLite/FwLiteShared/Services/ProjectServicesProvider.cs
  • backend/FwLite/FwLiteShared/Sync/SyncService.cs
  • backend/FwLite/LcmCrdt.Tests/CurrentProjectServiceTests.cs

Comment thread backend/FwLite/FwLiteShared/Auth/OAuthClient.cs
Comment thread backend/FwLite/FwLiteShared/Services/ProjectServicesProvider.cs Outdated
myieye and others added 2 commits July 27, 2026 17:48
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>
@myieye
myieye requested a review from hahn-kev July 27, 2026 16:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

💻 FW Lite issues related to the fw lite application, not miniLcm or crdt related

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FW Lite shows the wrong current user when a project's GUID exists on more than one logged-in server

2 participants