fix: cache bound identity outside UI actions

This commit is contained in:
2026-09-20 21:21:08 +08:00
parent e17124de59
commit baf7a47418
3 changed files with 44 additions and 85 deletions
+15 -16
View File
@@ -56,9 +56,8 @@ public sealed class WindowsAgentBackend(AccountBindingStore bindings, ServiceOpt
}
var binding = active[0];
using var scope = WechatChatClient.UseWindowTarget(binding.ProcessId, binding.WindowHandle);
var current = await WechatChatClient.GetMyInfoAsync(cancellationToken);
if (!BindingMatches(binding, current))
throw new ServiceException("AccountBindingStale", 409, "The listener binding is stale; bind the account again.");
if (string.IsNullOrWhiteSpace(binding.WechatId) && string.IsNullOrWhiteSpace(binding.Nickname))
throw new ServiceException("AccountBindingStale", 409, "The persisted account binding has no verified identity; bind the account again.");
var sessions = (await WechatChatClient.ListVisibleSessionsAsync(cancellationToken))
.Where(session => string.Equals(session.Name, WechatLocators.FileTransferAssistant, StringComparison.Ordinal)
&& !string.IsNullOrWhiteSpace(session.AutomationId))
@@ -73,9 +72,6 @@ public sealed class WindowsAgentBackend(AccountBindingStore bindings, ServiceOpt
await foreach (var item in WechatChatClient.ListenEventsAsync(TimeSpan.FromMinutes(5), checkpoint, cancellationToken,
session: WechatLocators.FileTransferAssistant))
{
var observedIdentity = await WechatChatClient.GetMyInfoAsync(cancellationToken);
if (!BindingMatches(binding, observedIdentity))
throw new ServiceException("AccountBindingStale", 409, "The listener binding changed; reporting is paused until the account is rebound.");
var eventType = item.Kind == MessageEventKind.MessageReceived ? "message" : "listener.reconnected";
yield return new AgentEvent(item.EventId, binding.AccountId, item.Session,
eventType, item.Message is null ? "listener state" : item.Message.Type.ToString(), item.ObservedAt,
@@ -352,7 +348,7 @@ public sealed class WindowsAgentBackend(AccountBindingStore bindings, ServiceOpt
}
public Task<SessionInfo> OpenSessionAsync(string? accountId, string automationId, CancellationToken cancellationToken) =>
ForAccountAsync(accountId, cancellationToken, () => OpenSessionAsync(automationId, cancellationToken));
ForAccountAsync(accountId, cancellationToken, () => OpenSessionAsync(automationId, cancellationToken), validateIdentity: true);
public async Task<SessionViewportInfo> ScrollSessionsAsync(string direction, int pages, CancellationToken cancellationToken)
{
@@ -362,7 +358,7 @@ public sealed class WindowsAgentBackend(AccountBindingStore bindings, ServiceOpt
}
public Task<SessionViewportInfo> ScrollSessionsAsync(string? accountId, string direction, int pages, CancellationToken cancellationToken) =>
ForAccountAsync(accountId, cancellationToken, () => ScrollSessionsAsync(direction, pages, cancellationToken));
ForAccountAsync(accountId, cancellationToken, () => ScrollSessionsAsync(direction, pages, cancellationToken), validateIdentity: true);
public async Task<IReadOnlyList<MessageInfo>> MessagesAsync(string? session, bool includeContent, CancellationToken cancellationToken)
{
@@ -390,10 +386,10 @@ public sealed class WindowsAgentBackend(AccountBindingStore bindings, ServiceOpt
throw new ServiceException(matches.Length == 0 ? "NotFound" : "AmbiguousTarget", 409, "The selected session is not unique or no longer visible.");
await WechatChatClient.SendTextAsync(text, cancellationToken, matches[0].Name);
return true;
});
}, validateIdentity: true);
}
private async Task<T> ForAccountAsync<T>(string? accountId, CancellationToken cancellationToken, Func<Task<T>> action)
private async Task<T> ForAccountAsync<T>(string? accountId, CancellationToken cancellationToken, Func<Task<T>> action, bool validateIdentity = false)
{
if (string.IsNullOrWhiteSpace(accountId))
throw new ServiceException("AccountIdRequired", 400, "accountId is required for every WeChat UI operation.");
@@ -408,12 +404,15 @@ public sealed class WindowsAgentBackend(AccountBindingStore bindings, ServiceOpt
if (target is null)
throw new ServiceException("AccountWindowUnavailable", 409, "The bound WeChat window is no longer available.");
using var scope = WechatChatClient.UseWindowTarget(binding.ProcessId, binding.WindowHandle);
var current = await WechatChatClient.GetMyInfoAsync(cancellationToken);
var identityMatches = !string.IsNullOrWhiteSpace(binding.WechatId)
? string.Equals(binding.WechatId, current.WechatId, StringComparison.OrdinalIgnoreCase)
: string.Equals(binding.Nickname, current.DisplayName, StringComparison.Ordinal);
if (!identityMatches)
throw new ServiceException("AccountBindingStale", 409, "The bound WeChat window identity changed; bind the account again.");
if (validateIdentity)
{
var current = await WechatChatClient.GetMyInfoAsync(cancellationToken);
var identityMatches = !string.IsNullOrWhiteSpace(binding.WechatId)
? string.Equals(binding.WechatId, current.WechatId, StringComparison.OrdinalIgnoreCase)
: string.Equals(binding.Nickname, current.DisplayName, StringComparison.Ordinal);
if (!identityMatches)
throw new ServiceException("AccountBindingStale", 409, "The bound WeChat window identity changed; bind the account again.");
}
return await action();
}