Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add use_https_scheme for Windows and Android #11477

Merged
merged 11 commits into from
Nov 5, 2024
6 changes: 6 additions & 0 deletions .changes/use_https_windows-and-android-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"tauri": "minor:feat"
"tauri-utils": "minor:feat"
---

Add `app > windows > useHttpsScheme` config option to choose whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android
7 changes: 7 additions & 0 deletions .changes/use_https_windows-and-android.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
"tauri": "minor:feat"
"tauri-runtime": "minor:feat"
"tauri-runtime-wry": "minor:feat"
---

Add `WebviewWindowBuilder/WebviewBuilder::use_https_scheme` to choose whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android
5 changes: 5 additions & 0 deletions crates/tauri-cli/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,11 @@
"description": "Whether browser extensions can be installed for the webview process\n\n ## Platform-specific:\n\n - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)\n - **MacOS / Linux / iOS / Android** - Unsupported.",
"default": false,
"type": "boolean"
},
"useHttpsScheme": {
"description": "Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.",
"default": false,
"type": "boolean"
}
},
"additionalProperties": false
Expand Down
49 changes: 48 additions & 1 deletion crates/tauri-cli/src/migrate/migrations/v1/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,28 @@ fn migrate_config(config: &mut Value) -> Result<MigratedConfig> {
migrated.permissions = permissions;
}

// dangerousUseHttpScheme/useHttpsScheme
let dangerouse_use_http = tauri_config
.get("security")
.and_then(|w| w.as_object())
.and_then(|w| {
w.get("dangerousUseHttpScheme")
.or_else(|| w.get("dangerous-use-http-scheme"))
})
.and_then(|v| v.as_bool())
.unwrap_or_default();

if let Some(windows) = tauri_config
.get_mut("windows")
.and_then(|w| w.as_array_mut())
{
for window in windows {
if let Some(window) = window.as_object_mut() {
window.insert("useHttpsScheme".to_string(), (!dangerouse_use_http).into());
}
}
}

// security
if let Some(security) = tauri_config
.get_mut("security")
Expand Down Expand Up @@ -802,7 +824,8 @@ mod test {
"pattern": { "use": "brownfield" },
"security": {
"csp": "default-src 'self' tauri:"
}
},
"windows": [{}]
}
});

Expand Down Expand Up @@ -907,6 +930,8 @@ mod test {
migrated["app"]["withGlobalTauri"],
original["build"]["withGlobalTauri"]
);

assert_eq!(migrated["app"]["windows"][0]["useHttpsScheme"], true);
}

#[test]
Expand Down Expand Up @@ -941,6 +966,28 @@ mod test {
);
}

#[test]
fn migrate_dangerous_use_http_scheme() {
let original = serde_json::json!({
"tauri": {
"windows": [{}],
"security": {
"dangerousUseHttpScheme": true,
}
}
});

let migrated = migrate(&original);
assert_eq!(
!migrated["app"]["windows"][0]["useHttpsScheme"]
.as_bool()
.unwrap(),
original["tauri"]["security"]["dangerousUseHttpScheme"]
.as_bool()
.unwrap()
);
}

#[test]
fn can_migrate_default_config() {
let original = serde_json::to_value(tauri_utils_v1::config::Config::default()).unwrap();
Expand Down
79 changes: 54 additions & 25 deletions crates/tauri-runtime-wry/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@ use tauri_runtime::{
monitor::Monitor,
webview::{DetachedWebview, DownloadEvent, PendingWebview, WebviewIpcHandler},
window::{
CursorIcon, DetachedWindow, DragDropEvent, PendingWindow, RawWindow, WebviewEvent,
WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints,
CursorIcon, DetachedWindow, DetachedWindowWebview, DragDropEvent, PendingWindow, RawWindow,
WebviewEvent, WindowBuilder, WindowBuilderBase, WindowEvent, WindowId, WindowSizeConstraints,
},
DeviceEventFilter, Error, EventLoopProxy, ExitRequestedEventAction, Icon, ProgressBarState,
ProgressBarStatus, Result, RunEvent, Runtime, RuntimeHandle, RuntimeInitArgs, UserAttentionType,
Expand Down Expand Up @@ -276,7 +276,16 @@ impl<T: UserEvent> Context<T> {
let label = pending.label.clone();
let context = self.clone();
let window_id = self.next_window_id();
let webview_id = pending.webview.as_ref().map(|_| context.next_webview_id());
let (webview_id, use_https_scheme) = pending
.webview
.as_ref()
.map(|w| {
(
Some(context.next_webview_id()),
w.webview_attributes.use_https_scheme,
)
})
.unwrap_or((None, false));

send_user_message(
self,
Expand All @@ -300,13 +309,19 @@ impl<T: UserEvent> Context<T> {
context: self.clone(),
};

let detached_webview = webview_id.map(|id| DetachedWebview {
label: label.clone(),
dispatcher: WryWebviewDispatcher {
window_id: Arc::new(Mutex::new(window_id)),
webview_id: id,
context: self.clone(),
},
let detached_webview = webview_id.map(|id| {
let webview = DetachedWebview {
label: label.clone(),
dispatcher: WryWebviewDispatcher {
window_id: Arc::new(Mutex::new(window_id)),
webview_id: id,
context: self.clone(),
},
};
DetachedWindowWebview {
webview,
use_https_scheme,
}
});

Ok(DetachedWindow {
Expand Down Expand Up @@ -746,6 +761,8 @@ impl WindowBuilder for WindowBuilderWrapper {
builder = builder.title_bar_style(TitleBarStyle::Visible);
}

builder = builder.title("Tauri App");

builder
}

Expand Down Expand Up @@ -2497,10 +2514,16 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
) -> Result<DetachedWindow<T, Self>> {
let label = pending.label.clone();
let window_id = self.context.next_window_id();
let webview_id = pending
let (webview_id, use_https_scheme) = pending
.webview
.as_ref()
.map(|_| self.context.next_webview_id());
.map(|w| {
(
Some(self.context.next_webview_id()),
w.webview_attributes.use_https_scheme,
)
})
.unwrap_or((None, false));

let window = create_window(
window_id,
Expand All @@ -2524,13 +2547,19 @@ impl<T: UserEvent> Runtime<T> for Wry<T> {
.borrow_mut()
.insert(window_id, window);

let detached_webview = webview_id.map(|id| DetachedWebview {
label: label.clone(),
dispatcher: WryWebviewDispatcher {
window_id: Arc::new(Mutex::new(window_id)),
webview_id: id,
context: self.context.clone(),
},
let detached_webview = webview_id.map(|id| {
let webview = DetachedWebview {
label: label.clone(),
dispatcher: WryWebviewDispatcher {
window_id: Arc::new(Mutex::new(window_id)),
webview_id: id,
context: self.context.clone(),
},
};
DetachedWindowWebview {
webview,
use_https_scheme,
}
});

Ok(DetachedWindow {
Expand Down Expand Up @@ -4026,6 +4055,11 @@ fn create_webview<T: UserEvent>(
.with_clipboard(webview_attributes.clipboard)
.with_hotkeys_zoom(webview_attributes.zoom_hotkeys_enabled);

#[cfg(any(target_os = "windows", target_os = "android"))]
{
webview_builder = webview_builder.with_https_scheme(webview_attributes.use_https_scheme);
}

if webview_attributes.drag_drop_handler_enabled {
let proxy = context.proxy.clone();
let window_id_ = window_id.clone();
Expand Down Expand Up @@ -4168,11 +4202,6 @@ fn create_webview<T: UserEvent>(
});
}

#[cfg(windows)]
{
webview_builder = webview_builder.with_https_scheme(false);
}

#[cfg(windows)]
{
webview_builder = webview_builder
Expand Down Expand Up @@ -4282,7 +4311,7 @@ fn create_webview<T: UserEvent>(
builder
}
}
.map_err(|e| Error::CreateWebview(Box::new(dbg!(e))))?;
.map_err(|e| Error::CreateWebview(Box::new(e)))?;

if kind == WebviewKind::WindowContent {
#[cfg(any(
Expand Down
18 changes: 18 additions & 0 deletions crates/tauri-runtime/src/webview.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ pub struct WebviewAttributes {
pub proxy_url: Option<Url>,
pub zoom_hotkeys_enabled: bool,
pub browser_extensions_enabled: bool,
pub use_https_scheme: bool,
}

impl From<&WindowConfig> for WebviewAttributes {
Expand All @@ -218,6 +219,7 @@ impl From<&WindowConfig> for WebviewAttributes {
.incognito(config.incognito)
.focused(config.focus)
.zoom_hotkeys_enabled(config.zoom_hotkeys_enabled)
.use_https_scheme(config.use_https_scheme)
.browser_extensions_enabled(config.browser_extensions_enabled);
#[cfg(any(not(target_os = "macos"), feature = "macos-private-api"))]
{
Expand Down Expand Up @@ -264,6 +266,7 @@ impl WebviewAttributes {
proxy_url: None,
zoom_hotkeys_enabled: false,
browser_extensions_enabled: false,
use_https_scheme: false,
}
}

Expand Down Expand Up @@ -388,6 +391,21 @@ impl WebviewAttributes {
self.browser_extensions_enabled = enabled;
self
}

/// Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.
///
/// ## Note
///
/// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.
///
/// ## Warning
///
/// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.
#[must_use]
pub fn use_https_scheme(mut self, enabled: bool) -> Self {
self.use_https_scheme = enabled;
self
}
}

/// IPC handler.
Expand Down
18 changes: 17 additions & 1 deletion crates/tauri-runtime/src/window.rs
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,23 @@ pub struct DetachedWindow<T: UserEvent, R: Runtime<T>> {
pub dispatcher: R::WindowDispatcher,

/// The webview dispatcher in case this window has an attached webview.
pub webview: Option<DetachedWebview<T, R>>,
pub webview: Option<DetachedWindowWebview<T, R>>,
}

/// A detached webview associated with a window.
#[derive(Debug)]
pub struct DetachedWindowWebview<T: UserEvent, R: Runtime<T>> {
pub webview: DetachedWebview<T, R>,
pub use_https_scheme: bool,
}

impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWindowWebview<T, R> {
fn clone(&self) -> Self {
Self {
webview: self.webview.clone(),
use_https_scheme: self.use_https_scheme,
}
}
}

impl<T: UserEvent, R: Runtime<T>> Clone for DetachedWindow<T, R> {
Expand Down
5 changes: 5 additions & 0 deletions crates/tauri-schema-generator/schemas/config.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -486,6 +486,11 @@
"description": "Whether browser extensions can be installed for the webview process\n\n ## Platform-specific:\n\n - **Windows**: Enables the WebView2 environment's [`AreBrowserExtensionsEnabled`](https://learn.microsoft.com/en-us/microsoft-edge/webview2/reference/winrt/microsoft_web_webview2_core/corewebview2environmentoptions?view=webview2-winrt-1.0.2739.15#arebrowserextensionsenabled)\n - **MacOS / Linux / iOS / Android** - Unsupported.",
"default": false,
"type": "boolean"
},
"useHttpsScheme": {
"description": "Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.\n\n ## Note\n\n Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.\n\n ## Warning\n\n Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.",
"default": false,
"type": "boolean"
}
},
"additionalProperties": false
Expand Down
17 changes: 16 additions & 1 deletion crates/tauri-utils/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1486,6 +1486,18 @@ pub struct WindowConfig {
/// - **MacOS / Linux / iOS / Android** - Unsupported.
#[serde(default)]
pub browser_extensions_enabled: bool,

/// Sets whether the custom protocols should use `https://<scheme>.localhost` instead of the default `http://<scheme>.localhost` on Windows and Android. Defaults to `false`.
///
/// ## Note
///
/// Using a `https` scheme will NOT allow mixed content when trying to fetch `http` endpoints and therefore will not match the behavior of the `<scheme>://localhost` protocols used on macOS and Linux.
///
/// ## Warning
///
/// Changing this value between releases will change the IndexedDB, cookies and localstorage location and your app will not be able to access the old data.
#[serde(default, alias = "use-https-scheme")]
pub use_https_scheme: bool,
}

impl Default for WindowConfig {
Expand Down Expand Up @@ -1534,6 +1546,7 @@ impl Default for WindowConfig {
proxy_url: None,
zoom_hotkeys_enabled: false,
browser_extensions_enabled: false,
use_https_scheme: false,
}
}
}
Expand Down Expand Up @@ -2505,6 +2518,7 @@ mod build {
let parent = opt_str_lit(self.parent.as_ref());
let zoom_hotkeys_enabled = self.zoom_hotkeys_enabled;
let browser_extensions_enabled = self.browser_extensions_enabled;
let use_https_scheme = self.use_https_scheme;

literal_struct!(
tokens,
Expand Down Expand Up @@ -2551,7 +2565,8 @@ mod build {
incognito,
parent,
zoom_hotkeys_enabled,
browser_extensions_enabled
browser_extensions_enabled,
use_https_scheme
);
}
}
Expand Down
3 changes: 2 additions & 1 deletion crates/tauri/scripts/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@
}

const osName = __TEMPLATE_os_name__
const protocolScheme = __TEMPLATE_protocol_scheme__

Object.defineProperty(window.__TAURI_INTERNALS__, 'convertFileSrc', {
value: function (filePath, protocol = 'asset') {
const path = encodeURIComponent(filePath)
return osName === 'windows' || osName === 'android'
? `http://${protocol}.localhost/${path}`
? `${protocolScheme}://${protocol}.localhost/${path}`
: `${protocol}://localhost/${path}`
}
})
Expand Down
Loading
Loading