diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
index 89ed9acf3..a30b8e966 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Languages/en.xaml
@@ -10,6 +10,7 @@
{0} by {1} {2}{3}Would you like to uninstall this plugin? After the uninstallation Flow will automatically restart.
{0} by {1} {2}{3}Would you like to install this plugin? After the installation Flow will automatically restart.
Plugin Install
+ Download and install {0}
Plugin Uninstall
Plugin installation in progress. Please wait...
Plugin successfully installed. Restarting Flow, please wait...
@@ -25,7 +26,9 @@
This plugin is already installed
Plugin Manifest Download Failed
Please check if you can connect to github.com. This error means you may not be able to install or update plugins.
-
+ Installing from an unknown source
+ You are installing this plugin from an unknown source and it may contain potential risks!{0}{0}Please ensure you understand where this plugin is from and that it is safe.{0}{0}Would you like to continue still?{0}{0}(You can switch off this warning via settings)
+
@@ -42,5 +45,7 @@
Suggest an enhancement or submit an issue to the plugin developer
Go to Flow's plugins repository
Visit the PluginsManifest repository to see community-made plugin submissions
-
+
+
+ Install from unknown source warning
\ No newline at end of file
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
index 89a8e0ff5..f445826fa 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Main.cs
@@ -55,7 +55,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
public async Task> QueryAsync(Query query, CancellationToken token)
{
- var search = query.Search.ToLower();
+ var search = query.Search;
if (string.IsNullOrWhiteSpace(search))
return pluginManager.GetDefaultHotKeys();
@@ -70,9 +70,13 @@ namespace Flow.Launcher.Plugin.PluginsManager
return search switch
{
- var s when s.StartsWith(Settings.HotKeyInstall) => await pluginManager.RequestInstallOrUpdate(s, token),
- var s when s.StartsWith(Settings.HotkeyUninstall) => pluginManager.RequestUninstall(s),
- var s when s.StartsWith(Settings.HotkeyUpdate) => await pluginManager.RequestUpdate(s, token),
+ //search could be url, no need ToLower() when passed in
+ var s when s.StartsWith(Settings.HotKeyInstall, StringComparison.OrdinalIgnoreCase)
+ => await pluginManager.RequestInstallOrUpdate(search, token),
+ var s when s.StartsWith(Settings.HotkeyUninstall, StringComparison.OrdinalIgnoreCase)
+ => pluginManager.RequestUninstall(search),
+ var s when s.StartsWith(Settings.HotkeyUpdate, StringComparison.OrdinalIgnoreCase)
+ => await pluginManager.RequestUpdate(search, token),
_ => pluginManager.GetDefaultHotKeys().Where(hotkey =>
{
hotkey.Score = StringMatcher.FuzzySearch(search, hotkey.Title).Score;
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
index adc4beb6c..f37dd86ea 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/PluginsManager.cs
@@ -166,17 +166,12 @@ namespace Flow.Launcher.Plugin.PluginsManager
catch (Exception e)
{
if (e is HttpRequestException)
- {
MessageBox.Show(Context.API.GetTranslation("plugin_pluginsmanager_download_error"),
Context.API.GetTranslation("plugin_pluginsmanager_downloading_plugin"));
- }
- else
- {
- Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
+ Context.API.ShowMsgError(Context.API.GetTranslation("plugin_pluginsmanager_install_error_title"),
string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_error_subtitle"),
plugin.Name));
- }
Log.Exception("PluginsManager", "An error occured while downloading plugin", e, "InstallOrUpdate");
@@ -206,7 +201,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (autocompletedResults.Any())
return autocompletedResults;
- var uninstallSearch = search.Replace(Settings.HotkeyUpdate, string.Empty).TrimStart();
+ var uninstallSearch = search.Replace(Settings.HotkeyUpdate, string.Empty, StringComparison.OrdinalIgnoreCase).TrimStart();
var resultsForUpdate =
from existingPlugin in Context.API.GetAllPlugins()
@@ -341,26 +336,46 @@ namespace Flow.Launcher.Plugin.PluginsManager
var result = new Result
{
- Title = filename,
- SubTitle = $"Download and Install from URL",
+ Title = string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_from_web"), filename),
+ SubTitle = plugin.UrlDownload,
IcoPath = icoPath,
Action = e =>
{
if (e.SpecialKeyState.CtrlPressed)
{
- SearchWeb.NewTabInBrowser(url);
+ SearchWeb.NewTabInBrowser(plugin.UrlDownload);
return ShouldHideWindow;
}
+ if (Settings.WarnFromUnknownSource)
+ {
+ if (!InstallSourceKnown(plugin.UrlDownload)
+ && MessageBox.Show(string.Format(Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning"),
+ Environment.NewLine),
+ Context.API.GetTranslation("plugin_pluginsmanager_install_unknown_source_warning_title"),
+ MessageBoxButton.YesNo) == MessageBoxResult.No)
+ return false;
+ }
+
Application.Current.MainWindow.Hide();
_ = InstallOrUpdate(plugin);
+
return ShouldHideWindow;
}
};
return new List { result };
}
-
+
+ private bool InstallSourceKnown(string url)
+ {
+ var author = url.Split('/')[3];
+ var acceptedSource = "https://github.com";
+ var contructedUrlPart = string.Format("{0}/{1}/", acceptedSource, author);
+
+ return url.StartsWith(acceptedSource) && Context.API.GetAllPlugins().Any(x => x.Metadata.Website.StartsWith(contructedUrlPart));
+ }
+
internal async ValueTask> RequestInstallOrUpdate(string searchName, CancellationToken token)
{
if (!PluginsManifest.UserPlugins.Any())
@@ -370,7 +385,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
token.ThrowIfCancellationRequested();
- var searchNameWithoutKeyword = searchName.Replace(Settings.HotKeyInstall, string.Empty).Trim();
+ var searchNameWithoutKeyword = searchName.Replace(Settings.HotKeyInstall, string.Empty, StringComparison.OrdinalIgnoreCase).Trim();
if (Uri.IsWellFormedUriString(searchNameWithoutKeyword, UriKind.Absolute)
&& searchNameWithoutKeyword.Split('.').Last() == zip)
@@ -468,7 +483,7 @@ namespace Flow.Launcher.Plugin.PluginsManager
if (autocompletedResults.Any())
return autocompletedResults;
- var uninstallSearch = search.Replace(Settings.HotkeyUninstall, string.Empty).TrimStart();
+ var uninstallSearch = search.Replace(Settings.HotkeyUninstall, string.Empty, StringComparison.OrdinalIgnoreCase).TrimStart();
var results = Context.API
.GetAllPlugins()
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
index 9c5b0d29f..a951010c0 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Settings.cs
@@ -7,8 +7,11 @@ namespace Flow.Launcher.Plugin.PluginsManager
internal class Settings
{
internal string HotKeyInstall { get; set; } = "install";
+
internal string HotkeyUninstall { get; set; } = "uninstall";
internal string HotkeyUpdate { get; set; } = "update";
+
+ public bool WarnFromUnknownSource { get; set; } = true;
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs
index 8ca4c614a..11303f472 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/ViewModels/SettingsViewModel.cs
@@ -14,5 +14,11 @@ namespace Flow.Launcher.Plugin.PluginsManager.ViewModels
Context = context;
Settings = settings;
}
+
+ public bool WarnFromUnknownSource
+ {
+ get => Settings.WarnFromUnknownSource;
+ set => Settings.WarnFromUnknownSource = value;
+ }
}
}
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml
index 89d27f6ff..d75803066 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml
@@ -3,10 +3,18 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
- xmlns:local="clr-namespace:Flow.Launcher.Plugin.PluginsManager.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
-
-
+
+
+
+
+
+
+
+
diff --git a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml.cs b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml.cs
index 703682e07..26668cc05 100644
--- a/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml.cs
+++ b/Plugins/Flow.Launcher.Plugin.PluginsManager/Views/PluginsManagerSettings.xaml.cs
@@ -16,7 +16,7 @@ namespace Flow.Launcher.Plugin.PluginsManager.Views
this.viewModel = viewModel;
- //RefreshView();
+ this.DataContext = viewModel;
}
}
}