Skip to content

Commit

Permalink
feat: add use_https_scheme for Windows and Android (#11477)
Browse files Browse the repository at this point in the history
* feat: add `use_https_scheme` for Windows and Android

closes #11252

* fix compilation

* Apply suggestions from code review

Co-authored-by: Fabian-Lars <[email protected]>

* change wording

* add migrations

* migrate `dangerousUseHttpScheme`

* fmt

* infer AssetResolver::get https scheme config

* fix tests

---------

Co-authored-by: Fabian-Lars <[email protected]>
Co-authored-by: Lucas Nogueira <[email protected]>
  • Loading branch information
3 people authored Nov 5, 2024
1 parent 058c0db commit f37e97d
Show file tree
Hide file tree
Showing 22 changed files with 358 additions and 79 deletions.
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 @@ -1519,6 +1519,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 @@ -1567,6 +1579,7 @@ impl Default for WindowConfig {
proxy_url: None,
zoom_hotkeys_enabled: false,
browser_extensions_enabled: false,
use_https_scheme: false,
}
}
}
Expand Down Expand Up @@ -2538,6 +2551,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 @@ -2584,7 +2598,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

0 comments on commit f37e97d

Please sign in to comment.