namespace MxGateway.Server.Diagnostics; public static class GatewayLogRedactor { public const string RedactedValue = "[redacted]"; private static readonly HashSet SensitiveCommandMethods = new(StringComparer.OrdinalIgnoreCase) { "AuthenticateUser", "WriteSecured", "WriteSecured2" }; public static bool IsCredentialBearingCommand(string? commandMethod) { return commandMethod is not null && SensitiveCommandMethods.Contains(commandMethod); } public static string? RedactApiKey(string? authorizationHeader) { if (string.IsNullOrWhiteSpace(authorizationHeader)) { return authorizationHeader; } const string bearerPrefix = "Bearer "; if (!authorizationHeader.StartsWith(bearerPrefix, StringComparison.OrdinalIgnoreCase)) { return RedactedValue; } string token = authorizationHeader[bearerPrefix.Length..].Trim(); if (!token.StartsWith("mxgw_", StringComparison.OrdinalIgnoreCase)) { return $"{bearerPrefix}{RedactedValue}"; } string[] tokenParts = token.Split('_', 3, StringSplitOptions.RemoveEmptyEntries); if (tokenParts.Length < 2) { return $"{bearerPrefix}mxgw_{RedactedValue}"; } return $"{bearerPrefix}mxgw_{tokenParts[1]}_{RedactedValue}"; } public static string? RedactClientIdentity(string? clientIdentity) { if (string.IsNullOrWhiteSpace(clientIdentity)) { return clientIdentity; } return clientIdentity.Contains("mxgw_", StringComparison.OrdinalIgnoreCase) ? RedactApiKey(clientIdentity) : clientIdentity; } public static object? RedactCommandValue( string? commandMethod, object? value, bool valueLoggingEnabled = false) { if (value is null) { return null; } if (!valueLoggingEnabled || IsCredentialBearingCommand(commandMethod)) { return RedactedValue; } return value; } }