mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-02-06 14:17:02 +00:00
use glob patterns by default
This commit is contained in:
parent
710256b20c
commit
e32108a453
@ -1168,13 +1168,13 @@
|
||||
]
|
||||
},
|
||||
"urls": {
|
||||
"description": "Only allow URLs matching the given pattern list when set.",
|
||||
"description": "Only allow URLs matching the given pattern list when set.\n\n By default it is a glob pattern, but can use the full [URLPattern] spec if the `url-pattern` feature is enabled.\n\n [URLPattern]: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/UrlPattern"
|
||||
"$ref": "#/definitions/UrlScope"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1194,13 +1194,13 @@
|
||||
]
|
||||
},
|
||||
"urls": {
|
||||
"description": "Only allow URLs matching the given pattern list when set.",
|
||||
"description": "Only allow URLs matching the given pattern list when set.\n\n By default it is a glob pattern, but can use the full [URLPattern] spec if the `url-pattern` feature is enabled.\n\n [URLPattern]: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/UrlPattern"
|
||||
"$ref": "#/definitions/UrlScope"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1224,7 +1224,20 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"UrlPattern": {
|
||||
"UrlScope": {
|
||||
"description": "A scope to match URLs.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "A [`GlobPattern`] to match URLs.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/GlobPattern"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"GlobPattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"SecurityConfig": {
|
||||
|
||||
@ -1168,13 +1168,13 @@
|
||||
]
|
||||
},
|
||||
"urls": {
|
||||
"description": "Only allow URLs matching the given pattern list when set.",
|
||||
"description": "Only allow URLs matching the given pattern list when set.\n\n By default it is a glob pattern, but can use the full [URLPattern] spec if the `url-pattern` feature is enabled.\n\n [URLPattern]: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/UrlPattern"
|
||||
"$ref": "#/definitions/UrlScope"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1194,13 +1194,13 @@
|
||||
]
|
||||
},
|
||||
"urls": {
|
||||
"description": "Only allow URLs matching the given pattern list when set.",
|
||||
"description": "Only allow URLs matching the given pattern list when set.\n\n By default it is a glob pattern, but can use the full [URLPattern] spec if the `url-pattern` feature is enabled.\n\n [URLPattern]: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern",
|
||||
"type": [
|
||||
"array",
|
||||
"null"
|
||||
],
|
||||
"items": {
|
||||
"$ref": "#/definitions/UrlPattern"
|
||||
"$ref": "#/definitions/UrlScope"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1224,7 +1224,20 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"UrlPattern": {
|
||||
"UrlScope": {
|
||||
"description": "A scope to match URLs.",
|
||||
"anyOf": [
|
||||
{
|
||||
"description": "A [`GlobPattern`] to match URLs.",
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/GlobPattern"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"GlobPattern": {
|
||||
"type": "string"
|
||||
},
|
||||
"SecurityConfig": {
|
||||
|
||||
@ -75,3 +75,4 @@ config-json5 = ["json5"]
|
||||
config-toml = []
|
||||
resources = ["walkdir"]
|
||||
html-manipulation = ["dep:html5ever", "dep:kuchiki"]
|
||||
url-pattern = []
|
||||
|
||||
@ -62,7 +62,7 @@ fn add_description(schema: Schema, description: impl Into<String>) -> Schema {
|
||||
pub mod parse;
|
||||
|
||||
use crate::{
|
||||
acl::capability::Capability, url::UrlPattern, TitleBarStyle, WindowEffect, WindowEffectState,
|
||||
acl::capability::Capability, url::UrlScope, TitleBarStyle, WindowEffect, WindowEffectState,
|
||||
};
|
||||
|
||||
pub use self::parse::parse;
|
||||
@ -1658,12 +1658,20 @@ pub enum OnNewWindow {
|
||||
/// Allow the window to be created using the default webview implementation.
|
||||
AllowDefault {
|
||||
/// Only allow URLs matching the given pattern list when set.
|
||||
urls: Option<Vec<UrlPattern>>,
|
||||
///
|
||||
/// By default it is a glob pattern, but can use the full [URLPattern] spec if the `url-pattern` feature is enabled.
|
||||
///
|
||||
/// [URLPattern]: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern
|
||||
urls: Option<Vec<UrlScope>>,
|
||||
},
|
||||
/// Allow the window to be created using a Tauri window.
|
||||
AllowTauriWindow {
|
||||
/// Only allow URLs matching the given pattern list when set.
|
||||
urls: Option<Vec<UrlPattern>>,
|
||||
///
|
||||
/// By default it is a glob pattern, but can use the full [URLPattern] spec if the `url-pattern` feature is enabled.
|
||||
///
|
||||
/// [URLPattern]: https://developer.mozilla.org/en-US/docs/Web/API/URLPattern
|
||||
urls: Option<Vec<UrlScope>>,
|
||||
},
|
||||
/// Deny the window from being created.
|
||||
#[default]
|
||||
@ -3557,11 +3565,11 @@ mod build {
|
||||
|
||||
tokens.append_all(match self {
|
||||
Self::AllowDefault { urls } => {
|
||||
let urls = opt_vec_lit(urls.as_ref(), url_pattern_lit);
|
||||
let urls = opt_vec_lit(urls.as_ref(), url_scope_lit);
|
||||
quote! { #prefix::AllowDefault { urls: #urls } }
|
||||
}
|
||||
Self::AllowTauriWindow { urls } => {
|
||||
let urls = opt_vec_lit(urls.as_ref(), url_pattern_lit);
|
||||
let urls = opt_vec_lit(urls.as_ref(), url_scope_lit);
|
||||
quote! { #prefix::AllowTauriWindow { urls: #urls } }
|
||||
}
|
||||
Self::Deny => quote! { #prefix::Deny },
|
||||
|
||||
@ -11,7 +11,7 @@ use quote::{quote, ToTokens};
|
||||
use serde_json::Value as JsonValue;
|
||||
use url::Url;
|
||||
|
||||
use crate::url::UrlPattern;
|
||||
use crate::url::{GlobPattern, UrlPattern, UrlScope};
|
||||
|
||||
/// Write a `TokenStream` of the `$struct`'s fields to the `$tokens`.
|
||||
///
|
||||
@ -100,6 +100,29 @@ pub fn url_pattern_lit(url: &UrlPattern) -> TokenStream {
|
||||
quote! { #url.parse().unwrap() }
|
||||
}
|
||||
|
||||
/// Creates a [`GlobPattern`] constructor `TokenStream`.
|
||||
pub fn glob_pattern_lit(pattern: &GlobPattern) -> TokenStream {
|
||||
let pattern = pattern.0.as_str();
|
||||
quote! { #pattern.parse().unwrap() }
|
||||
}
|
||||
|
||||
/// Creates a [`UrlScope`] constructor `TokenStream`.
|
||||
pub fn url_scope_lit(url: &UrlScope) -> TokenStream {
|
||||
let prefix = quote! { ::tauri::utils::url::UrlScope };
|
||||
match url {
|
||||
#[cfg(feature = "url-pattern")]
|
||||
UrlScope::UrlPattern(url) => {
|
||||
let url = url.as_str();
|
||||
quote! { #prefix::UrlPattern(#url.parse().unwrap()) }
|
||||
}
|
||||
#[cfg(not(feature = "url-pattern"))]
|
||||
UrlScope::Glob(glob) => {
|
||||
let pattern = glob.0.as_str();
|
||||
quote! { #prefix::Glob(#pattern.parse().unwrap()) }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a map constructor, mapping keys and values with other `TokenStream`s.
|
||||
///
|
||||
/// This function is pretty generic because the types of keys AND values get transformed.
|
||||
|
||||
@ -9,6 +9,77 @@ use std::{str::FromStr, sync::Arc};
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
use url::Url;
|
||||
|
||||
/// A scope to match URLs.
|
||||
#[derive(Debug, Clone, Deserialize, Serialize, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||
#[serde(untagged)]
|
||||
pub enum UrlScope {
|
||||
/// A [`UrlPattern`] to match URLs.
|
||||
///
|
||||
/// This is only available if the `url-pattern` feature is enabled.
|
||||
#[cfg(feature = "url-pattern")]
|
||||
UrlPattern(UrlPattern),
|
||||
/// A [`GlobPattern`] to match URLs.
|
||||
#[cfg(not(feature = "url-pattern"))]
|
||||
Glob(GlobPattern),
|
||||
}
|
||||
|
||||
impl UrlScope {
|
||||
/// Test if a given URL is matched by the scope.
|
||||
pub fn test(&self, url: &Url) -> bool {
|
||||
match self {
|
||||
#[cfg(feature = "url-pattern")]
|
||||
Self::UrlPattern(pattern) => pattern.test(url),
|
||||
#[cfg(not(feature = "url-pattern"))]
|
||||
Self::Glob(pattern) => pattern.0.matches(url.as_str()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A [`glob::Pattern`] to match URLs.
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct GlobPattern(pub(crate) glob::Pattern);
|
||||
|
||||
#[cfg(feature = "schema")]
|
||||
impl schemars::JsonSchema for GlobPattern {
|
||||
fn schema_name() -> String {
|
||||
"GlobPattern".to_string()
|
||||
}
|
||||
|
||||
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
String::json_schema(_gen)
|
||||
}
|
||||
}
|
||||
|
||||
impl FromStr for GlobPattern {
|
||||
type Err = glob::PatternError;
|
||||
|
||||
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||
glob::Pattern::new(s).map(Self)
|
||||
}
|
||||
}
|
||||
|
||||
impl Serialize for GlobPattern {
|
||||
fn serialize<S>(&self, serializer: S) -> std::result::Result<S::Ok, S::Error>
|
||||
where
|
||||
S: Serializer,
|
||||
{
|
||||
serializer.serialize_str(&self.0.as_str())
|
||||
}
|
||||
}
|
||||
|
||||
impl<'de> Deserialize<'de> for GlobPattern {
|
||||
fn deserialize<D>(deserializer: D) -> std::result::Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
let s = String::deserialize(deserializer)?;
|
||||
glob::Pattern::new(&s)
|
||||
.map(Self)
|
||||
.map_err(serde::de::Error::custom)
|
||||
}
|
||||
}
|
||||
|
||||
/// UrlPattern to match URLs.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct UrlPattern(Arc<urlpattern::UrlPattern>, String);
|
||||
@ -73,7 +144,7 @@ impl UrlPattern {
|
||||
&self.1
|
||||
}
|
||||
|
||||
/// Test if a given URL matches the pattern.
|
||||
/// Test if a given URL is matched by the pattern.
|
||||
pub fn test(&self, url: &Url) -> bool {
|
||||
self
|
||||
.0
|
||||
|
||||
@ -221,6 +221,7 @@ image-png = ["image/png"]
|
||||
macos-proxy = ["tauri-runtime-wry?/macos-proxy"]
|
||||
dynamic-acl = []
|
||||
specta = ["dep:specta"]
|
||||
url-pattern = ["tauri-utils/url-pattern"]
|
||||
|
||||
[[example]]
|
||||
name = "commands"
|
||||
|
||||
@ -37,6 +37,7 @@
|
||||
//! - **macos-proxy**: Adds support for [`WebviewBuilder::proxy_url`] on macOS. Requires macOS 14+.
|
||||
//! - **specta**: Add support for [`specta::specta`](https://docs.rs/specta/%5E2.0.0-rc.9/specta/attr.specta.html) with Tauri arguments such as [`State`](crate::State), [`Window`](crate::Window) and [`AppHandle`](crate::AppHandle)
|
||||
//! - **dynamic-acl** *(enabled by default)*: Enables you to add ACLs at runtime, notably it enables the [`Manager::add_capability`] function.
|
||||
//! - **url-pattern**: Enables using the [URLPattern] spec for URL scopes on JavaScript APIs.
|
||||
//!
|
||||
//! ## Cargo allowlist features
|
||||
//!
|
||||
|
||||
@ -906,14 +906,14 @@ interface WebviewOptions {
|
||||
*
|
||||
* 'allowDefault' lets the webview open the URL using the native implementation.
|
||||
* 'allowTauriWindow' creates a Tauri window to load the URL.
|
||||
* Additionally you can provide a list of filters to only allow URLs matching certain {@link https://developer.mozilla.org/en-US/docs/Web/API/URLPattern|URL patterns}.
|
||||
* Additionally you can provide a list of filters to only allow URLs matching certain glob patterns.
|
||||
* It can leverage the {@link https://developer.mozilla.org/en-US/docs/Web/API/URLPattern|URL pattern spec} if the `url-pattern` Cargo feature is enabled.
|
||||
*
|
||||
* A new window is requested to be opened by the {@link https://developer.mozilla.org/en-US/docs/Web/API/Window/open|window.open API}.
|
||||
*
|
||||
* ## Platform-specific
|
||||
*
|
||||
* - **Android / iOS**: Not supported.
|
||||
*
|
||||
* */
|
||||
onNewWindow?: OnNewWindow
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user