diff --git a/uds-auth/lib/client.js b/uds-auth/lib/client.js index 82b3203a..f9b681ea 100644 --- a/uds-auth/lib/client.js +++ b/uds-auth/lib/client.js @@ -146,13 +146,10 @@ window.__ModuleLoader__.load({ } function reconnectAfterLogin() { - try { - if (typeof window.__udsAuthReconnect === 'function') { - window.__udsAuthReconnect() - return - } - } catch { /* fall through */ } - window.location.reload() + // Soft WS reconnect often keeps a workspace.follow subscription that was + // opened while anonymous (empty workspace list). Full reload makes the + // first follow run with fallback/UDS cookies so historical workspaces show. + try { window.location.reload() } catch { /* ignore */ } } function getAuthToken() { diff --git a/uds-auth/lib/dsh-acl.js b/uds-auth/lib/dsh-acl.js index 1cf717d5..b78892c4 100644 --- a/uds-auth/lib/dsh-acl.js +++ b/uds-auth/lib/dsh-acl.js @@ -535,9 +535,22 @@ export function installDshAcl(ctx, { const origFollow = wc.follow.bind(wc) wc.follow = async function* (signal) { - const identity = getUserContext() + let identity = getUserContext() + // Subscribe can race ahead of WS message-listener ALS bind (common right + // after fallback login / soft reconnect). Wait briefly before treating + // the stream as anonymous — otherwise every historical workspace is + // dropped and sessions collapse into 未分组. + if (!identity?.empNo) { + const deadline = Date.now() + 800 + while (!identity?.empNo && Date.now() < deadline) { + await new Promise((r) => setTimeout(r, 40)) + identity = getUserContext() + } + } // Super / fallback: passthrough — never drop historical workspaces. - if (identity?.permissions?.canViewAllSessions) { + if (identity?.permissions?.canViewAllSessions + || identity?.role === 'fallback_admin' + || identity?.role === 'super_admin') { yield* origFollow(signal) return }