From 8cf4ae94bd45a35297aedee32c2772e4120435d6 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Fri, 23 May 2025 16:59:09 +0300 Subject: [PATCH 01/17] Add CLI 'remove' command to remove Dev Proxy certificate --- .../CertRemoveCommandHandler.cs | 26 +++++++++++++++++++ dev-proxy/ProxyHost.cs | 10 ++++++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs diff --git a/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs b/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs new file mode 100644 index 00000000..4950e57c --- /dev/null +++ b/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs @@ -0,0 +1,26 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace DevProxy.CommandHandlers; + +public static class CertRemoveCommandHandler +{ + public static void RemoveCert(ILogger logger) + { + logger.LogTrace("RemoveCert() called"); + + try + { + logger.LogInformation("Uninstalling the root certificate..."); + ProxyEngine.ProxyServer.CertificateManager.RemoveTrustedRootCertificate(machineTrusted: false); + logger.LogInformation("DONE"); + } + catch (Exception ex) + { + logger.LogError(ex, "Error removing certificate"); + } + + logger.LogTrace("RemoveCert() finished"); + } +} diff --git a/dev-proxy/ProxyHost.cs b/dev-proxy/ProxyHost.cs index c48018ba..15c23dc0 100755 --- a/dev-proxy/ProxyHost.cs +++ b/dev-proxy/ProxyHost.cs @@ -382,7 +382,8 @@ private static Command CreateCertCommand(ILogger logger) var sortedCommands = new[] { - CreateCertEnsureCommand(logger) + CreateCertEnsureCommand(logger), + CreateCertRemoveCommand(logger), }.OrderByName(); certCommand.AddCommands(sortedCommands); @@ -396,6 +397,13 @@ private static Command CreateCertEnsureCommand(ILogger logger) return certEnsureCommand; } + private static Command CreateCertRemoveCommand(ILogger logger) + { + var certRemoveCommand = new Command("remove", "Remove the certificate from Root Store"); + certRemoveCommand.SetHandler(() => CertRemoveCommandHandler.RemoveCert(logger)); + return certRemoveCommand; + } + private static Command CreateJwtCommand() { var jwtCommand = new Command("jwt", "Manage JSON Web Tokens"); From c42e7bea5f1e5d0cd8bc17319b3d6252dba95f7a Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Fri, 23 May 2025 17:03:07 +0300 Subject: [PATCH 02/17] Update win-installers to remove certificate when uninstalling --- install-beta.iss | 4 ++++ install.iss | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/install-beta.iss b/install-beta.iss index 09d58b0c..87f68d11 100644 --- a/install-beta.iss +++ b/install-beta.iss @@ -7,6 +7,7 @@ #define MyAppVersion "0.28.0-beta.1" #define MyAppPublisher ".NET Foundation" #define MyAppURL "https://aka.ms/devproxy" +#define DevProxyExecutable "devproxy.exe" [Setup] ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. @@ -45,6 +46,9 @@ Source: ".\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsu [UninstallDelete] Type:files;Name:"{app}\rootCert.pfx" +[UninstallRun] +Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "DelService"; Flags: runhidden; + [Code] procedure RemovePath(Path: string); var diff --git a/install.iss b/install.iss index 20fa9c78..52680ed0 100644 --- a/install.iss +++ b/install.iss @@ -7,6 +7,7 @@ #define MyAppVersion "0.28.0" #define MyAppPublisher ".NET Foundation" #define MyAppURL "https://aka.ms/devproxy" +#define DevProxyExecutable "devproxy.exe" [Setup] ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. @@ -45,6 +46,9 @@ Source: ".\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsu [UninstallDelete] Type:files;Name:"{app}\rootCert.pfx" +[UninstallRun] +Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "DelService"; Flags: runhidden; + [Code] procedure RemovePath(Path: string); var From f1a17e1534a56a32b01277515e5744c934ef69c7 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Sat, 24 May 2025 08:54:20 +0300 Subject: [PATCH 03/17] Fix beta executable name --- install-beta.iss | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/install-beta.iss b/install-beta.iss index 87f68d11..3336823c 100644 --- a/install-beta.iss +++ b/install-beta.iss @@ -7,7 +7,7 @@ #define MyAppVersion "0.28.0-beta.1" #define MyAppPublisher ".NET Foundation" #define MyAppURL "https://aka.ms/devproxy" -#define DevProxyExecutable "devproxy.exe" +#define DevProxyExecutable "devproxy-beta.exe" [Setup] ; NOTE: The value of AppId uniquely identifies this application. Do not use the same AppId value in installers for other applications. From 144a2b231c8a5855912ee8fa2f961276a302bd69 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Sat, 24 May 2025 08:58:59 +0300 Subject: [PATCH 04/17] Adjust certificate removal identifier of installer --- install-beta.iss | 2 +- install.iss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/install-beta.iss b/install-beta.iss index 3336823c..0812ebd6 100644 --- a/install-beta.iss +++ b/install-beta.iss @@ -47,7 +47,7 @@ Source: ".\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsu Type:files;Name:"{app}\rootCert.pfx" [UninstallRun] -Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "DelService"; Flags: runhidden; +Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "RemoveCert"; Flags: runhidden; [Code] procedure RemovePath(Path: string); diff --git a/install.iss b/install.iss index 52680ed0..57c80792 100644 --- a/install.iss +++ b/install.iss @@ -47,7 +47,7 @@ Source: ".\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsu Type:files;Name:"{app}\rootCert.pfx" [UninstallRun] -Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "DelService"; Flags: runhidden; +Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "RemoveCert"; Flags: runhidden; [Code] procedure RemovePath(Path: string); From 0fef20d648eaea45a9b2f608dceeab68b68b48ba Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Tue, 3 Jun 2025 21:46:11 +0300 Subject: [PATCH 05/17] fix: Add prompt confirmation to remove certificates and --force option to bypass --- .../CertRemoveCommandHandler.cs | 46 ++++++++++++++++++- dev-proxy/ProxyHost.cs | 7 ++- 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs b/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs index 4950e57c..c3c854c8 100644 --- a/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs +++ b/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs @@ -2,25 +2,67 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using System.CommandLine; +using System.CommandLine.Invocation; + namespace DevProxy.CommandHandlers; public static class CertRemoveCommandHandler { - public static void RemoveCert(ILogger logger) + public static void RemoveCert(ILogger logger, InvocationContext invocationContext, Option forceOption) { logger.LogTrace("RemoveCert() called"); + ArgumentNullException.ThrowIfNull(logger); + ArgumentNullException.ThrowIfNull(invocationContext); + ArgumentNullException.ThrowIfNull(forceOption); try { + var isForced = invocationContext.ParseResult.GetValueForOption(forceOption); + if (!isForced) + { + var isConfirmed = PromptConfirmation("Do you want to remove the root certificate", defaultValue: false); + if (!isConfirmed) + { + return; + } + } + logger.LogInformation("Uninstalling the root certificate..."); + ProxyEngine.ProxyServer.CertificateManager.RemoveTrustedRootCertificate(machineTrusted: false); + logger.LogInformation("DONE"); } catch (Exception ex) { logger.LogError(ex, "Error removing certificate"); } + finally + { + logger.LogTrace("RemoveCert() finished"); + } + } - logger.LogTrace("RemoveCert() finished"); + private static bool PromptConfirmation(string message, bool defaultValue) + { + while (true) + { + Console.Write(message + $" ({(defaultValue ? "Y/n" : "y/N")}): "); + var answer = Console.ReadLine(); + + if (string.IsNullOrWhiteSpace(answer)) + { + return defaultValue; + } + else if (answer.StartsWith("y", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + else if (answer.StartsWith("n", StringComparison.OrdinalIgnoreCase)) + { + return false; + } + } } } diff --git a/dev-proxy/ProxyHost.cs b/dev-proxy/ProxyHost.cs index 15c23dc0..64d446c4 100755 --- a/dev-proxy/ProxyHost.cs +++ b/dev-proxy/ProxyHost.cs @@ -399,8 +399,13 @@ private static Command CreateCertEnsureCommand(ILogger logger) private static Command CreateCertRemoveCommand(ILogger logger) { + var forceOption = new Option("--force", "Force the root certificate removal"); + forceOption.AddAlias("-f"); + var certRemoveCommand = new Command("remove", "Remove the certificate from Root Store"); - certRemoveCommand.SetHandler(() => CertRemoveCommandHandler.RemoveCert(logger)); + certRemoveCommand.SetHandler((context) => CertRemoveCommandHandler.RemoveCert(logger, context, forceOption)); + + certRemoveCommand.AddOptions(new[] { forceOption }.OrderByName()); return certRemoveCommand; } From 234fa26c82513acf96470edb2411dd3dbee2b781 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Wed, 4 Jun 2025 13:43:08 +0300 Subject: [PATCH 06/17] Update installers to remove cert silently --- install-beta.iss | 2 +- install.iss | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/install-beta.iss b/install-beta.iss index 0812ebd6..831729b6 100644 --- a/install-beta.iss +++ b/install-beta.iss @@ -47,7 +47,7 @@ Source: ".\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsu Type:files;Name:"{app}\rootCert.pfx" [UninstallRun] -Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "RemoveCert"; Flags: runhidden; +Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove --force"; RunOnceId: "RemoveCert"; Flags: runhidden; [Code] procedure RemovePath(Path: string); diff --git a/install.iss b/install.iss index 57c80792..437ba969 100644 --- a/install.iss +++ b/install.iss @@ -47,7 +47,7 @@ Source: ".\*"; DestDir: "{app}"; Flags: ignoreversion recursesubdirs createallsu Type:files;Name:"{app}\rootCert.pfx" [UninstallRun] -Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove"; RunOnceId: "RemoveCert"; Flags: runhidden; +Filename: "{app}\{#DevProxyExecutable}"; Parameters: "cert remove --force"; RunOnceId: "RemoveCert"; Flags: runhidden; [Code] procedure RemovePath(Path: string); From 1ada2184de88ceda1326f09a84cffa6e00d0631c Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Fri, 6 Jun 2025 11:38:44 +0300 Subject: [PATCH 07/17] Remove trusted certificate on Mac --- .../CertRemoveCommandHandler.cs | 25 +++++++++++++++++++ dev-proxy/dev-proxy.csproj | 3 +++ dev-proxy/remove-cert.sh | 25 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 dev-proxy/remove-cert.sh diff --git a/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs b/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs index c3c854c8..10afceb2 100644 --- a/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs +++ b/dev-proxy/CommandHandlers/CertRemoveCommandHandler.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. +using DevProxy.Abstractions; using System.CommandLine; using System.CommandLine.Invocation; +using System.Diagnostics; +using Titanium.Web.Proxy.Helpers; namespace DevProxy.CommandHandlers; @@ -30,6 +33,7 @@ public static void RemoveCert(ILogger logger, InvocationContext invocationContex logger.LogInformation("Uninstalling the root certificate..."); + RemoveTrustedCertificateOnMac(); ProxyEngine.ProxyServer.CertificateManager.RemoveTrustedRootCertificate(machineTrusted: false); logger.LogInformation("DONE"); @@ -65,4 +69,25 @@ private static bool PromptConfirmation(string message, bool defaultValue) } } } + + private static void RemoveTrustedCertificateOnMac() + { + if (!RunTime.IsMac) + { + return; + } + + var bashScriptPath = Path.Join(ProxyUtils.AppFolder, "remove-cert.sh"); + ProcessStartInfo startInfo = new() + { + FileName = "/bin/bash", + Arguments = bashScriptPath, + UseShellExecute = false, + CreateNoWindow = true, + }; + + var process = new Process() { StartInfo = startInfo }; + process.Start(); + process.WaitForExit(); + } } diff --git a/dev-proxy/dev-proxy.csproj b/dev-proxy/dev-proxy.csproj index ff9f0727..e5a77556 100644 --- a/dev-proxy/dev-proxy.csproj +++ b/dev-proxy/dev-proxy.csproj @@ -62,6 +62,9 @@ PreserveNewest + + PreserveNewest + Always diff --git a/dev-proxy/remove-cert.sh b/dev-proxy/remove-cert.sh new file mode 100644 index 00000000..67ccc24c --- /dev/null +++ b/dev-proxy/remove-cert.sh @@ -0,0 +1,25 @@ +#!/bin/bash +set -e + +if [ "$(uname -s)" != "Darwin" ]; then + echo "Error: this shell script should be run on macOS." + exit 1 +fi + +echo -e "\nRemove the self-signed certificate from your Keychain." + +cert_name="Dev Proxy CA" +cert_filename="dev-proxy-ca.pem" + +# export cert from keychain to PEM +echo "Exporting '$cert_name' certificate..." +security find-certificate -c "$cert_name" -a -p > "$cert_filename" + +# add trusted cert to keychain +echo "Removing Dev Proxy trust settings..." +security remove-trusted-cert "$cert_filename" + +# remove exported cert +echo "Cleaning up..." +rm "$cert_filename" +echo -e "\033[0;32mDONE\033[0m\n" \ No newline at end of file From ede001a731fc2abebf31fe7f9e73a7b2aa113705 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Fri, 6 Jun 2025 14:41:21 +0300 Subject: [PATCH 08/17] Fix project updating resources only if newer one --- dev-proxy/dev-proxy.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dev-proxy/dev-proxy.csproj b/dev-proxy/dev-proxy.csproj index e5a77556..84d0493e 100644 --- a/dev-proxy/dev-proxy.csproj +++ b/dev-proxy/dev-proxy.csproj @@ -66,7 +66,7 @@ PreserveNewest - Always + PreserveNewest PreserveNewest From d6e31c83a2e1f821d3cb71a6e4577b454605e00d Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Wed, 11 Jun 2025 11:53:45 +0300 Subject: [PATCH 09/17] Add HasRunFlag class and refactor IsFirstRun() --- DevProxy/Proxy/ProxyEngine.cs | 37 ++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/DevProxy/Proxy/ProxyEngine.cs b/DevProxy/Proxy/ProxyEngine.cs index 314e454d..12fac3e0 100755 --- a/DevProxy/Proxy/ProxyEngine.cs +++ b/DevProxy/Proxy/ProxyEngine.cs @@ -179,7 +179,7 @@ private void FirstRunSetup() { if (!RunTime.IsMac || _config.NoFirstRun || - !IsFirstRun() || + !HasRunFlag.IsFirstRun() || !_config.InstallCert) { return; @@ -615,21 +615,40 @@ private static void ToggleSystemProxy(ToggleSystemProxyAction toggle, string? ip process.WaitForExit(); } - private static bool IsFirstRun() + internal static class HasRunFlag { - var firstRunFilePath = Path.Combine(ProxyUtils.AppFolder!, ".hasrun"); - if (File.Exists(firstRunFilePath)) + private static readonly string filename = Path.Combine(ProxyUtils.AppFolder!, ".hasrun"); + + public static bool IsFirstRun() { - return false; + if (File.Exists(filename)) + { + return false; + } + + return CreateFlag(); } - try + private static bool CreateFlag() { - File.WriteAllText(firstRunFilePath, ""); + try + { + File.WriteAllText(filename, ""); + } + catch + { + return false; + } + return true; } - catch { } - return true; + public static void RemoveFlag() + { + if (File.Exists(filename)) + { + File.Delete(filename); + } + } } private static int GetProcessId(TunnelConnectSessionEventArgs e) From 11d7ebf79914e1c8a565b24eea4ef85b620f4e45 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Wed, 11 Jun 2025 11:54:46 +0300 Subject: [PATCH 10/17] Add .hasrun flag removal along with certificates removal (#1241) --- DevProxy/Commands/CertCommand.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/DevProxy/Commands/CertCommand.cs b/DevProxy/Commands/CertCommand.cs index 2194bcb8..652175e6 100644 --- a/DevProxy/Commands/CertCommand.cs +++ b/DevProxy/Commands/CertCommand.cs @@ -9,6 +9,7 @@ using System.CommandLine.Parsing; using System.Diagnostics; using Titanium.Web.Proxy.Helpers; +using static DevProxy.Proxy.ProxyEngine; namespace DevProxy.Commands; @@ -136,5 +137,7 @@ private static void RemoveTrustedCertificateOnMac() using var process = new Process() { StartInfo = startInfo }; _ = process.Start(); process.WaitForExit(); + + HasRunFlag.RemoveFlag(); } } \ No newline at end of file From 83918ff303c39171f1c29ce7175d2f07a4715b4e Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Wed, 11 Jun 2025 12:02:39 +0300 Subject: [PATCH 11/17] Hide possible exceptions during .hasrun flag deletion (#1241) --- DevProxy/Proxy/ProxyEngine.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/DevProxy/Proxy/ProxyEngine.cs b/DevProxy/Proxy/ProxyEngine.cs index 12fac3e0..4d1ec8a9 100755 --- a/DevProxy/Proxy/ProxyEngine.cs +++ b/DevProxy/Proxy/ProxyEngine.cs @@ -644,10 +644,14 @@ private static bool CreateFlag() public static void RemoveFlag() { - if (File.Exists(filename)) + try { - File.Delete(filename); + if (File.Exists(filename)) + { + File.Delete(filename); + } } + catch { } } } From 99e243609a99f4933dc9ad1ef1e75e100c016f11 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Thu, 12 Jun 2025 15:58:48 +0300 Subject: [PATCH 12/17] Remove redundant -Flag suffix --- DevProxy/Commands/CertCommand.cs | 2 +- DevProxy/Proxy/ProxyEngine.cs | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/DevProxy/Commands/CertCommand.cs b/DevProxy/Commands/CertCommand.cs index 652175e6..065ef0df 100644 --- a/DevProxy/Commands/CertCommand.cs +++ b/DevProxy/Commands/CertCommand.cs @@ -138,6 +138,6 @@ private static void RemoveTrustedCertificateOnMac() _ = process.Start(); process.WaitForExit(); - HasRunFlag.RemoveFlag(); + HasRunFlag.Remove(); } } \ No newline at end of file diff --git a/DevProxy/Proxy/ProxyEngine.cs b/DevProxy/Proxy/ProxyEngine.cs index 4d1ec8a9..7453be32 100755 --- a/DevProxy/Proxy/ProxyEngine.cs +++ b/DevProxy/Proxy/ProxyEngine.cs @@ -626,10 +626,10 @@ public static bool IsFirstRun() return false; } - return CreateFlag(); + return Create(); } - private static bool CreateFlag() + private static bool Create() { try { @@ -642,7 +642,7 @@ private static bool CreateFlag() return true; } - public static void RemoveFlag() + public static void Remove() { try { From ff20aad9d0e3b4681d2206bb8d9de993debd59a7 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Thu, 12 Jun 2025 16:00:40 +0300 Subject: [PATCH 13/17] Rename defaultValue to acceptByDefault parameter --- DevProxy/Commands/CertCommand.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/DevProxy/Commands/CertCommand.cs b/DevProxy/Commands/CertCommand.cs index 065ef0df..11735e01 100644 --- a/DevProxy/Commands/CertCommand.cs +++ b/DevProxy/Commands/CertCommand.cs @@ -72,7 +72,7 @@ public void RemoveCert(InvocationContext invocationContext) var isForced = invocationContext.ParseResult.GetValueForOption(_forceOption); if (!isForced) { - var isConfirmed = PromptConfirmation("Do you want to remove the root certificate", defaultValue: false); + var isConfirmed = PromptConfirmation("Do you want to remove the root certificate", acceptByDefault: false); if (!isConfirmed) { return; @@ -96,16 +96,16 @@ public void RemoveCert(InvocationContext invocationContext) } } - private static bool PromptConfirmation(string message, bool defaultValue) + private static bool PromptConfirmation(string message, bool acceptByDefault) { while (true) { - Console.Write(message + $" ({(defaultValue ? "Y/n" : "y/N")}): "); + Console.Write(message + $" ({(acceptByDefault ? "Y/n" : "y/N")}): "); var answer = Console.ReadLine(); if (string.IsNullOrWhiteSpace(answer)) { - return defaultValue; + return acceptByDefault; } else if (string.Equals("y", answer, StringComparison.OrdinalIgnoreCase)) { From 20a23f8ec4fc6a5d9fc2e4b4ddd2f3667fdee233 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Thu, 12 Jun 2025 16:57:34 +0300 Subject: [PATCH 14/17] Use 'var' instead of explicit type --- DevProxy/Commands/CertCommand.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DevProxy/Commands/CertCommand.cs b/DevProxy/Commands/CertCommand.cs index 11735e01..d67186fd 100644 --- a/DevProxy/Commands/CertCommand.cs +++ b/DevProxy/Commands/CertCommand.cs @@ -126,7 +126,7 @@ private static void RemoveTrustedCertificateOnMac() } var bashScriptPath = Path.Join(ProxyUtils.AppFolder, "remove-cert.sh"); - ProcessStartInfo startInfo = new() + var startInfo = new ProcessStartInfo() { FileName = "/bin/bash", Arguments = bashScriptPath, From 079f5ba1a6dbddf1cd67e6f35dc1386c2c392140 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Thu, 12 Jun 2025 17:17:36 +0300 Subject: [PATCH 15/17] Rename IsFirstRun to CreateIfMissing function --- DevProxy/Proxy/ProxyEngine.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DevProxy/Proxy/ProxyEngine.cs b/DevProxy/Proxy/ProxyEngine.cs index 7453be32..6ac3a84f 100755 --- a/DevProxy/Proxy/ProxyEngine.cs +++ b/DevProxy/Proxy/ProxyEngine.cs @@ -179,7 +179,7 @@ private void FirstRunSetup() { if (!RunTime.IsMac || _config.NoFirstRun || - !HasRunFlag.IsFirstRun() || + !HasRunFlag.CreateIfMissing() || !_config.InstallCert) { return; @@ -619,7 +619,7 @@ internal static class HasRunFlag { private static readonly string filename = Path.Combine(ProxyUtils.AppFolder!, ".hasrun"); - public static bool IsFirstRun() + public static bool CreateIfMissing() { if (File.Exists(filename)) { From 763ffdecd9ae818a1b14a9d209bce1f35292c027 Mon Sep 17 00:00:00 2001 From: Artem Azaraev Date: Thu, 12 Jun 2025 17:26:35 +0300 Subject: [PATCH 16/17] Move HasRunFlag to Abstractions.Utils --- DevProxy.Abstractions/Utils/HasRunFlag.cs | 45 +++++++++++++++++++++++ DevProxy/Commands/CertCommand.cs | 1 - DevProxy/Proxy/ProxyEngine.cs | 40 -------------------- 3 files changed, 45 insertions(+), 41 deletions(-) create mode 100644 DevProxy.Abstractions/Utils/HasRunFlag.cs diff --git a/DevProxy.Abstractions/Utils/HasRunFlag.cs b/DevProxy.Abstractions/Utils/HasRunFlag.cs new file mode 100644 index 00000000..652ae868 --- /dev/null +++ b/DevProxy.Abstractions/Utils/HasRunFlag.cs @@ -0,0 +1,45 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + +namespace DevProxy.Abstractions.Utils; + +public static class HasRunFlag +{ + private static readonly string filename = Path.Combine(ProxyUtils.AppFolder!, ".hasrun"); + + public static bool CreateIfMissing() + { + if (File.Exists(filename)) + { + return false; + } + + return Create(); + } + + private static bool Create() + { + try + { + File.WriteAllText(filename, ""); + } + catch + { + return false; + } + return true; + } + + public static void Remove() + { + try + { + if (File.Exists(filename)) + { + File.Delete(filename); + } + } + catch { } + } +} diff --git a/DevProxy/Commands/CertCommand.cs b/DevProxy/Commands/CertCommand.cs index d67186fd..78bb7d85 100644 --- a/DevProxy/Commands/CertCommand.cs +++ b/DevProxy/Commands/CertCommand.cs @@ -9,7 +9,6 @@ using System.CommandLine.Parsing; using System.Diagnostics; using Titanium.Web.Proxy.Helpers; -using static DevProxy.Proxy.ProxyEngine; namespace DevProxy.Commands; diff --git a/DevProxy/Proxy/ProxyEngine.cs b/DevProxy/Proxy/ProxyEngine.cs index 6ac3a84f..55949f37 100755 --- a/DevProxy/Proxy/ProxyEngine.cs +++ b/DevProxy/Proxy/ProxyEngine.cs @@ -615,46 +615,6 @@ private static void ToggleSystemProxy(ToggleSystemProxyAction toggle, string? ip process.WaitForExit(); } - internal static class HasRunFlag - { - private static readonly string filename = Path.Combine(ProxyUtils.AppFolder!, ".hasrun"); - - public static bool CreateIfMissing() - { - if (File.Exists(filename)) - { - return false; - } - - return Create(); - } - - private static bool Create() - { - try - { - File.WriteAllText(filename, ""); - } - catch - { - return false; - } - return true; - } - - public static void Remove() - { - try - { - if (File.Exists(filename)) - { - File.Delete(filename); - } - } - catch { } - } - } - private static int GetProcessId(TunnelConnectSessionEventArgs e) { if (RunTime.IsWindows) From aa4963bc3ee2c4e64e50e8a9f2671f5843bee464 Mon Sep 17 00:00:00 2001 From: Waldek Mastykarz Date: Fri, 13 Jun 2025 08:23:19 +0200 Subject: [PATCH 17/17] Minor fixes --- DevProxy/Commands/CertCommand.cs | 5 +---- {DevProxy.Abstractions/Utils => DevProxy}/HasRunFlag.cs | 6 ++++-- 2 files changed, 5 insertions(+), 6 deletions(-) rename {DevProxy.Abstractions/Utils => DevProxy}/HasRunFlag.cs (91%) diff --git a/DevProxy/Commands/CertCommand.cs b/DevProxy/Commands/CertCommand.cs index 78bb7d85..fe4607bf 100644 --- a/DevProxy/Commands/CertCommand.cs +++ b/DevProxy/Commands/CertCommand.cs @@ -15,7 +15,7 @@ namespace DevProxy.Commands; sealed class CertCommand : Command { private readonly ILogger _logger; - private readonly Option _forceOption = new(["--force", "-f"], "Force the root certificate removal"); + private readonly Option _forceOption = new(["--force", "-f"], "Don't prompt for confirmation when removing the certificate"); public CertCommand(ILogger logger) : base("cert", "Manage the Dev Proxy certificate") @@ -62,9 +62,6 @@ private async Task EnsureCertAsync() public void RemoveCert(InvocationContext invocationContext) { _logger.LogTrace("RemoveCert() called"); - ArgumentNullException.ThrowIfNull(_logger); - ArgumentNullException.ThrowIfNull(invocationContext); - ArgumentNullException.ThrowIfNull(_forceOption); try { diff --git a/DevProxy.Abstractions/Utils/HasRunFlag.cs b/DevProxy/HasRunFlag.cs similarity index 91% rename from DevProxy.Abstractions/Utils/HasRunFlag.cs rename to DevProxy/HasRunFlag.cs index 652ae868..3ad9afe1 100644 --- a/DevProxy.Abstractions/Utils/HasRunFlag.cs +++ b/DevProxy/HasRunFlag.cs @@ -2,9 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. -namespace DevProxy.Abstractions.Utils; +using DevProxy.Abstractions.Utils; -public static class HasRunFlag +namespace DevProxy; + +static class HasRunFlag { private static readonly string filename = Path.Combine(ProxyUtils.AppFolder!, ".hasrun");