diff --git a/doc/cascadia/profiles.schema.json b/doc/cascadia/profiles.schema.json index be78d1c36c..1bb60a2374 100644 --- a/doc/cascadia/profiles.schema.json +++ b/doc/cascadia/profiles.schema.json @@ -2462,6 +2462,13 @@ }, "type": "array" }, + "safeUriSchemes": { + "description": "Specifies a list of URI schemes that are considered safe. No confirmation will be required to open URIs with these schemes.", + "items": { + "type": "string" + }, + "type": "array" + }, "rendering.graphicsAPI": { "description": "Direct3D 11 provides a more performant and feature-rich experience, whereas Direct2D is more stable. The default option \"Automatic\" will pick the API that best fits your graphics hardware. If you experience significant issues, consider using Direct2D.", "type": "string", diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 658323384d..8597f1d28f 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -3144,13 +3144,15 @@ namespace winrt::TerminalApp::implementation return true; } - bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) + bool TerminalPage::_IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const { - if (parsedUri.SchemeName() == L"http" || parsedUri.SchemeName() == L"https") + const auto& schemeName = parsedUri.SchemeName(); + + if (schemeName == L"http" || schemeName == L"https") { return true; } - if (parsedUri.SchemeName() == L"file") + if (schemeName == L"file") { static const auto pathext{ wil::TryGetEnvironmentVariableW(L"PATHEXT") }; const auto filename = parsedUri.Path(); @@ -3164,6 +3166,16 @@ namespace winrt::TerminalApp::implementation return true; } + if (const auto& safeSchemes = _settings.GlobalSettings().SafeUriSchemes()) + { + for (const auto& scheme : safeSchemes) + { + if (til::equals_insensitive_ascii(schemeName, scheme)) + { + return true; + } + } + } return false; } diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index 7e7b6d1eba..5dc1ff5d0d 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -418,7 +418,7 @@ namespace winrt::TerminalApp::implementation safe_void_coroutine _OpenHyperlinkHandler(const IInspectable sender, const Microsoft::Terminal::Control::OpenHyperlinkEventArgs eventArgs); static bool _IsUriSupported(const winrt::Windows::Foundation::Uri& parsedUri); - static bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri); + bool _IsUriConsideredSomewhatSafe(const winrt::Windows::Foundation::Uri& parsedUri) const; void _ShowCouldNotOpenDialog(winrt::hstring reason, winrt::hstring uri); bool _CopyText(bool dismissSelection, bool singleLine, bool withControlSequences, Microsoft::Terminal::Control::CopyFormat formats); diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp index d7c0e5a6a7..db8bcf2d1f 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.cpp @@ -102,6 +102,14 @@ winrt::com_ptr GlobalAppSettings::Copy() const globals->_DisabledProfileSources->Append(src); } } + if (_SafeUriSchemes) + { + globals->_SafeUriSchemes = winrt::single_threaded_vector(); + for (const auto& src : *_SafeUriSchemes) + { + globals->_SafeUriSchemes->Append(src); + } + } for (const auto& parent : _parents) { diff --git a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl index e003660f32..994299e5d7 100644 --- a/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl +++ b/src/cascadia/TerminalSettingsModel/GlobalAppSettings.idl @@ -105,6 +105,7 @@ namespace Microsoft.Terminal.Settings.Model INHERITABLE_SETTING(Boolean, EnableUnfocusedAcrylic); INHERITABLE_SETTING(Boolean, AllowHeadless); INHERITABLE_SETTING(String, SearchWebDefaultQueryUrl); + INHERITABLE_SETTING(IVector, SafeUriSchemes); Windows.Foundation.Collections.IMapView ColorSchemes(); void AddColorScheme(ColorScheme scheme); diff --git a/src/cascadia/TerminalSettingsModel/MTSMSettings.h b/src/cascadia/TerminalSettingsModel/MTSMSettings.h index 9040f89cbf..69a2badc01 100644 --- a/src/cascadia/TerminalSettingsModel/MTSMSettings.h +++ b/src/cascadia/TerminalSettingsModel/MTSMSettings.h @@ -62,6 +62,7 @@ Author(s): X(bool, MinimizeToNotificationArea, "minimizeToNotificationArea", false) \ X(bool, AlwaysShowNotificationIcon, "alwaysShowNotificationIcon", false) \ X(winrt::Windows::Foundation::Collections::IVector, DisabledProfileSources, "disabledProfileSources", nullptr) \ + X(winrt::Windows::Foundation::Collections::IVector, SafeUriSchemes, "safeUriSchemes", nullptr) \ X(bool, ShowAdminShield, "showAdminShield", true) \ X(bool, TrimPaste, "trimPaste", true) \ X(bool, EnableColorSelection, "experimental.enableColorSelection", false) \ diff --git a/src/cascadia/UnitTests_SettingsModel/SerializationTests.cpp b/src/cascadia/UnitTests_SettingsModel/SerializationTests.cpp index 3112f83939..cbda46e9fb 100644 --- a/src/cascadia/UnitTests_SettingsModel/SerializationTests.cpp +++ b/src/cascadia/UnitTests_SettingsModel/SerializationTests.cpp @@ -461,6 +461,7 @@ namespace SettingsModelUnitTests "$schema" : "https://aka.ms/terminal-profiles-schema", "defaultProfile": "{61c54bbd-1111-5271-96e7-009a87ff44bf}", "disabledProfileSources": [ "Windows.Terminal.Wsl" ], + "safeUriSchemes": [ "vscode" ], "newTabMenu": [ {