feat: validate single-client broadcast operations
Build web service image / build (push) Successful in 1m9s

This commit is contained in:
2026-09-19 14:33:26 +08:00
parent e321d38fa3
commit c7c0ab273f
62 changed files with 2861 additions and 12651 deletions
+11 -7
View File
@@ -136,7 +136,7 @@ internal sealed class TrayApplicationContext : ApplicationContext
};
Directory.CreateDirectory(initial.DataDirectory);
WriteJson(configPath, initial);
WriteCredentials(initial.CredentialFile, initialToken);
WriteCredentials(initial.CredentialFile, initialToken, initial.EnableValidationOperations);
options = initial;
return true;
}
@@ -154,7 +154,7 @@ internal sealed class TrayApplicationContext : ApplicationContext
if (changed) WriteJson(configPath, normalized);
Directory.CreateDirectory(normalized.DataDirectory);
// Always rewrite one canonical record so old/malformed/multi-record files self-heal on tray startup.
WriteCredentials(normalized.CredentialFile, token);
WriteCredentials(normalized.CredentialFile, token, normalized.EnableValidationOperations);
options = normalized;
return changed;
}
@@ -177,7 +177,8 @@ internal sealed class TrayApplicationContext : ApplicationContext
DataDirectory = dataDirectory,
Remote = source.Remote,
Reporting = source.Reporting,
RemoteConfigurationFile = source.RemoteConfigurationFile
RemoteConfigurationFile = source.RemoteConfigurationFile,
EnableValidationOperations = source.EnableValidationOperations
};
private ServiceOptions ReadOptions() =>
@@ -190,7 +191,7 @@ internal sealed class TrayApplicationContext : ApplicationContext
var loaded = ReadOptions();
loaded.Validate();
options = loaded;
service = ServiceHost.Build(loaded, new WindowsAgentBackend(new AccountBindingStore(loaded)), logPath: GetLogPath());
service = ServiceHost.Build(loaded, new WindowsAgentBackend(new AccountBindingStore(loaded), loaded), logPath: GetLogPath());
try
{
await service.StartAsync();
@@ -283,7 +284,7 @@ internal sealed class TrayApplicationContext : ApplicationContext
{
EnsureConfiguration();
if (ServiceSettingsEditor.Show(options!) is not { } edited) return;
WriteCredentials(edited.CredentialFile, edited.AccessToken!);
WriteCredentials(edited.CredentialFile, edited.AccessToken!, edited.EnableValidationOperations);
WriteJson(configPath, edited);
_ = ReloadAsync();
}
@@ -329,12 +330,15 @@ internal sealed class TrayApplicationContext : ApplicationContext
base.Dispose(disposing);
}
private static void WriteCredentials(string path, string token)
private static void WriteCredentials(string path, string token, bool includeValidationWrite)
{
var temporary = path + ".tmp";
var permissions = includeValidationWrite
? new[] { "read", "content", "write", "manage" }
: new[] { "read", "content", "manage" };
WriteJson(temporary, new[]
{
new ServiceCredential("local-admin", ServiceOptions.HashToken(token), ["read", "content", "manage"], [])
new ServiceCredential("local-admin", ServiceOptions.HashToken(token), permissions, [])
});
File.Move(temporary, path, true);
}