using ZB.MOM.WW.Telemetry.Serilog;
namespace ZB.MOM.WW.MxGateway.Server.Diagnostics;
///
/// Adapts the static to the shared seam
/// so the telemetry RedactionEnricher masks API-key/credential material on every log event.
///
public sealed class GatewayLogRedactorSeam : ILogRedactor
{
private static readonly string[] IdentityKeys = ["ClientIdentity", "authorization", "Authorization"];
/// Property name carrying the MXAccess command method, which gates value redaction.
private const string CommandMethodProperty = "CommandMethod";
/// Property name carrying a command payload value that may bear credentials.
private const string CommandValueProperty = "CommandValue";
///
/// Masks API-key/credential material in known identity-bearing log properties, and any
/// command payload value.
///
/// The log event property dictionary to redact in place.
public void Redact(IDictionary properties)
{
ArgumentNullException.ThrowIfNull(properties);
foreach (var key in IdentityKeys)
{
if (properties.TryGetValue(key, out var value) && value is string s)
{
properties[key] = GatewayLogRedactor.RedactClientIdentity(s);
}
}
RedactCommandValue(properties);
foreach (string key in properties.Keys.ToList())
{
if (key.Contains("password", StringComparison.OrdinalIgnoreCase) && properties[key] is not null)
{
properties[key] = GatewayLogRedactor.RedactedValue;
}
}
}
///
/// Masks a command payload value. Value logging is off here — the seam exposes no opt-in — so
/// every non-null value is masked, credential-bearing command or not.
///
/// The log event property dictionary to redact in place.
private static void RedactCommandValue(IDictionary properties)
{
if (!properties.TryGetValue(CommandValueProperty, out object? value) || value is null)
{
return;
}
string? commandMethod = properties.TryGetValue(CommandMethodProperty, out object? method)
? method as string
: null;
properties[CommandValueProperty] = GatewayLogRedactor.RedactCommandValue(commandMethod, value);
}
}