Three related issues with the confirm command implementation, per docs:
- The confirm command takes Base64 (unpadded) encoded values for the yes and no strings. The current implementation does not base64-decode them.
- The ok response must have either a "yes" or "no" value in the command argument. The current implementation uses an empty argument array.
- The user likely should not be required to type or copy/paste in the full displayed text and instead should just give a simple simple yes/no indication. (Upstream age, for example, uses just 1 and 2, IIRC).
Here's corrected code (.NET Standard 2.0) for the first two issues:
private void HandleConfirm(PluginConnection conn, string[] args, byte[] body)
{
var message = EncodingExtended.UTF8.GetString(body);
var yes = args.Length > 0 ? EncodingExtended.UTF8.GetString(Base64Unpadded.Decode(args[0].AsSpan())) : "yes";
var no = args.Length > 1 ? EncodingExtended.UTF8.GetString(Base64Unpadded.Decode(args[1].AsSpan())) : null;
var confirmed = _callbacks.Confirm(message, yes, no);
conn.WriteStanza("ok", new[] { confirmed ? "yes" : "no" }, Array.Empty<byte>());
}
Here's suggested code (.NET Standard 2.0) for the third issue:
public bool Confirm(string message, string yes, string no)
{
var options = $"[y: {yes}/n: {no ?? "no"}] (y/N): ";
Console.Error.Write($"{message} {options}");
string response;
bool result;
bool first = true;
do
{
if (!first)
{
Console.Error.Write("Please enter y (yes) or n (no) (y/N): ");
}
response = Console.ReadLine()?.Trim() ?? "";
first = false;
} while (!TryParseConfirmResponse(response, out result));
return result;
}
private static bool TryParseConfirmResponse(string response, out bool parsed)
{
if (response.Equals("y", StringComparison.OrdinalIgnoreCase) ||
response.Equals("yes", StringComparison.OrdinalIgnoreCase))
{
parsed = true;
return true;
}
else if (response.Length == 0 ||
response.Equals("n", StringComparison.OrdinalIgnoreCase) ||
response.Equals("no", StringComparison.OrdinalIgnoreCase))
{
parsed = false;
return true;
}
else
{
parsed = default;
return false;
}
}
}
Three related issues with the confirm command implementation, per docs:
Here's corrected code (.NET Standard 2.0) for the first two issues:
Here's suggested code (.NET Standard 2.0) for the third issue: