Skip to content

Fix local sign-in losing its user account (empty read-only workspace)#1739

Open
iyernaveenr wants to merge 2 commits into
eigent-ai:mainfrom
iyernaveenr:naveen_r_iyer/fix-local-login-user-id
Open

Fix local sign-in losing its user account (empty read-only workspace)#1739
iyernaveenr wants to merge 2 commits into
eigent-ai:mainfrom
iyernaveenr:naveen_r_iyer/fix-local-login-user-id

Conversation

@iyernaveenr

Copy link
Copy Markdown

Problem

In fully local (self-hosted) mode, the app can end up showing only an empty, read-only "Legacy Space": no Projects in the sidebar, composer disabled with "Legacy Spaces are read-only", and no way to pick a model -- even though all of the user's Spaces, Projects, and chat history are intact on the server.

Root cause

The local auto-login endpoint (POST /api/v1/user/auto-login) returns only token and email -- no user id. The client's setAuth therefore stores user_id: null. Space hydration filters server Spaces by ownership, comparing each Space's user_id against the canonicalized local id; with no id, the canonical value is the local sentinel, which matches nothing, so every server-owned Space is silently discarded and only the locally fabricated legacy Space remains. The access token itself carries the user id in its payload the whole time; the client just never read it.

Fix

  • Server: include user_id in the auto-login response (LoginResponse gains an optional user_id).
  • Client: when a login response omits the id, recover it from the access token's payload in setAuth (defensive for all login paths).
  • Client: repair already-persisted sessions at rehydrate -- an existing install with a stored token but no stored user id recovers the id from the token at startup, without requiring the user to sign in again.

Testing

  • Reproduced the degraded state (persisted user_id: null, valid token): Space list showed only "Legacy Space" while an authenticated /api/v1/spaces request returned all Spaces. After the fix, reloading the app recovers the id from the token and the user's Spaces and Projects reappear.
  • POST /api/v1/user/auto-login now returns user_id (verified against a running local server).
  • tsc passes; the changed server files compile; store test suites pass. Token-decoding helper handles malformed/absent tokens by returning null (no behavior change for the hosted login path, which already supplies an id).

The local auto-login response carried no user id, so the client stored
none and every server-owned Space was filtered out client-side, leaving
an empty read-only workspace. Return the user id from auto-login,
recover it from the access token when a login response omits it, and
repair already-persisted sessions at rehydrate so existing installs
recover without signing in again.

Signed-off-by: Naveen R. Iyer <iyernaveenr@gmail.com>
@Douglasymlai

Copy link
Copy Markdown
Contributor

@iyernaveenr Thanks for working on this. There is a blocking issue with the persisted-session repair. The recovery logic is inside the Zustand migrate callback, but the auth persistence version remains 10, which is also the current version on main. Zustand only invokes migrate when the stored version differs, so affected existing version-10 sessions with a valid token and user_id: null will bypass this repair and remain in the empty Legacy Space state.

Please bump the auth persistence version (for example, to 11) or move the normalization to a path that runs on every rehydration. A regression test loading a version-10 persisted state with user_id: null would also help verify the upgrade path.

@4pmtong, please leave any additional comments or suggestions on this issue.

Bump the auth persistence version so migrate re-runs for sessions at the current version and recovers the id from the token.

Signed-off-by: Naveen R. Iyer <iyernaveenr@gmail.com>
@iyernaveenr

Copy link
Copy Markdown
Author

Thanks for the careful review and for pinpointing the version-gating -- that analysis is exactly right.

the auth persistence version remains 10 ... Zustand only invokes migrate when the stored version differs, so affected existing version-10 sessions ... will bypass this repair

Fixed by bumping the persistence version so migrate re-runs for existing sessions and recovers the id from the token.

A regression test loading a version-10 persisted state ... would also help

A test driving this through the store is blocked by a circular dependency between the auth store and the i18n module (the current suite mocks the store for the same reason). I can add the regression test if the token-to-id recovery is first extracted into a standalone module so it can be exercised directly -- happy to do that if preferred.

@Douglasymlai

Copy link
Copy Markdown
Contributor

Looks good to me. Thanks for your contribution. I verified the version-10 persisted-session migration: it upgrades to version 11, restores the user ID from the token, and the expected Spaces, Projects, composer, and model controls remain available.

@4pmtong Please provide the second review, particularly for the backend changes to the local auto-login response and LoginResponse model.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants