From bbda16cd58c1537c1542d4792f387d7df21686fe Mon Sep 17 00:00:00 2001
From: Lauren Ciha <64796985+lauren-ciha@users.noreply.github.com>
Date: Thu, 26 Sep 2024 13:35:11 -0700
Subject: [PATCH] Fix crash on SSH wallet widget (#3895)

* Prevent crash with catch statement

* Update HandleConnect for new args.Data structure

* Refactor JSON string wrapping

* Clean up styling

* Remove Newtonsoft dependency from SSHWalletWidget

* User/krschau/fix ssh widget crash (#3900)

---------

Co-authored-by: Kristen Schau <47155823+krschau@users.noreply.github.com>
---
 .../Widgets/SSHWalletWidget.cs                | 13 +++++-
 .../ViewModels/WidgetViewModel.cs             | 44 +++++++++----------
 2 files changed, 32 insertions(+), 25 deletions(-)

diff --git a/extensions/CoreWidgetProvider/Widgets/SSHWalletWidget.cs b/extensions/CoreWidgetProvider/Widgets/SSHWalletWidget.cs
index 2e78000dd6..181d4de9ce 100644
--- a/extensions/CoreWidgetProvider/Widgets/SSHWalletWidget.cs
+++ b/extensions/CoreWidgetProvider/Widgets/SSHWalletWidget.cs
@@ -144,13 +144,24 @@ public override void OnCustomizationRequested(WidgetCustomizationRequestedArgs c
         SetConfigure();
     }
 
+    // This function assumes arg.Data will be a json string object with the following structure:
+    // { "data": "hostname" }
     private void HandleConnect(WidgetActionInvokedArgs args)
     {
+        var jsonObject = JsonDocument.Parse(args.Data).RootElement;
+        var host = jsonObject.GetProperty("data").GetString();
+
+        if (string.IsNullOrEmpty(host))
+        {
+            Log.Error("Invalid data received for HandleConnect.");
+            return;
+        }
+
         var cmd = new Process();
         cmd.StartInfo = new ProcessStartInfo
         {
             FileName = "cmd.exe",
-            Arguments = $"/k \"ssh {args.Data}\"",
+            Arguments = $"/k \"ssh {host}\"",
             UseShellExecute = true,
         };
 
diff --git a/tools/Dashboard/DevHome.Dashboard/ViewModels/WidgetViewModel.cs b/tools/Dashboard/DevHome.Dashboard/ViewModels/WidgetViewModel.cs
index eaf2824c1e..4c69b9b962 100644
--- a/tools/Dashboard/DevHome.Dashboard/ViewModels/WidgetViewModel.cs
+++ b/tools/Dashboard/DevHome.Dashboard/ViewModels/WidgetViewModel.cs
@@ -25,7 +25,6 @@
 using Microsoft.UI.Xaml.Controls;
 using Microsoft.Windows.Widgets;
 using Microsoft.Windows.Widgets.Hosts;
-using Newtonsoft.Json.Linq;
 using Serilog;
 
 namespace DevHome.Dashboard.ViewModels;
@@ -311,20 +310,29 @@ private Grid GetErrorCard(string error, string subError = null)
         return grid;
     }
 
-    private string MergeJsonData(string jsonStringA, string jsonStringB)
+    private Newtonsoft.Json.Linq.JObject WrapJsonString(string jsonString)
     {
-        if (string.IsNullOrEmpty(jsonStringA))
+        return new Newtonsoft.Json.Linq.JObject { ["data"] = jsonString };
+    }
+
+    private string MergeJsonData(Windows.Data.Json.JsonValue actionValue, Windows.Data.Json.JsonObject inputsObject)
+    {
+        Newtonsoft.Json.Linq.JObject objA = [];
+        Newtonsoft.Json.Linq.JObject objB = [];
+
+        if (actionValue?.ValueType == Windows.Data.Json.JsonValueType.Object)
         {
-            return jsonStringB;
+            objA = Newtonsoft.Json.Linq.JObject.Parse(actionValue.Stringify());
         }
-
-        if (string.IsNullOrEmpty(jsonStringB))
+        else if (actionValue?.ValueType == Windows.Data.Json.JsonValueType.String)
         {
-            return jsonStringA;
+            objA = WrapJsonString(actionValue.Stringify());
         }
 
-        var objA = JObject.Parse(jsonStringA);
-        var objB = JObject.Parse(jsonStringB);
+        if (inputsObject?.ValueType != Windows.Data.Json.JsonValueType.Null)
+        {
+            objB = Newtonsoft.Json.Linq.JObject.Parse(inputsObject.Stringify());
+        }
 
         objA.Merge(objB);
 
@@ -341,22 +349,10 @@ private async void HandleAdaptiveAction(RenderedAdaptiveCard sender, AdaptiveAct
         }
         else if (args.Action is AdaptiveExecuteAction executeAction)
         {
-            var actionData = string.Empty;
-            var inputsData = string.Empty;
-
-            var dataType = executeAction.DataJson.ValueType;
-            if (dataType != Windows.Data.Json.JsonValueType.Null)
-            {
-                actionData = executeAction.DataJson.Stringify();
-            }
-
-            var inputType = args.Inputs.AsJson().ValueType;
-            if (inputType != Windows.Data.Json.JsonValueType.Null)
-            {
-                inputsData = args.Inputs.AsJson().Stringify();
-            }
+            Windows.Data.Json.JsonValue actionValue = executeAction.DataJson;
+            Windows.Data.Json.JsonObject inputsObject = args.Inputs.AsJson();
 
-            var dataToSend = MergeJsonData(actionData, inputsData);
+            var dataToSend = MergeJsonData(actionValue, inputsObject);
 
             _log.Information($"Verb = {executeAction.Verb}, Data = {dataToSend}");
             await Widget.NotifyActionInvokedAsync(executeAction.Verb, dataToSend);