mirror of
https://github.com/tauri-apps/tauri.git
synced 2024-08-16 19:30:27 +03:00
refactor(acl): use URLPattern instead of glob for remote URLs (#9116)
This commit is contained in:
parent
9dc9ca6e38
commit
4ef17d0833
6
.changes/acl-urlpattern.md
Normal file
6
.changes/acl-urlpattern.md
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
---
|
||||||
|
"tauri": patch:breaking
|
||||||
|
"tauri-utils": patch:breaking
|
||||||
|
---
|
||||||
|
|
||||||
|
The ACL configuration for remote URLs now uses the URLPattern standard instead of glob patterns.
|
57
Cargo.lock
generated
57
Cargo.lock
generated
@ -3642,6 +3642,7 @@ dependencies = [
|
|||||||
"tracing",
|
"tracing",
|
||||||
"tray-icon",
|
"tray-icon",
|
||||||
"url",
|
"url",
|
||||||
|
"urlpattern",
|
||||||
"uuid",
|
"uuid",
|
||||||
"webkit2gtk",
|
"webkit2gtk",
|
||||||
"webview2-com",
|
"webview2-com",
|
||||||
@ -3796,6 +3797,7 @@ dependencies = [
|
|||||||
"phf 0.11.2",
|
"phf 0.11.2",
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
"quote",
|
"quote",
|
||||||
|
"regex",
|
||||||
"schemars",
|
"schemars",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
@ -3806,6 +3808,7 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
"toml 0.8.2",
|
"toml 0.8.2",
|
||||||
"url",
|
"url",
|
||||||
|
"urlpattern",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -4179,6 +4182,47 @@ version = "0.1.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-char-property"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
|
||||||
|
dependencies = [
|
||||||
|
"unic-char-range",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-char-range"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-common"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-ucd-ident"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987"
|
||||||
|
dependencies = [
|
||||||
|
"unic-char-property",
|
||||||
|
"unic-char-range",
|
||||||
|
"unic-ucd-version",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-ucd-version"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
|
||||||
|
dependencies = [
|
||||||
|
"unic-common",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
@ -4234,6 +4278,19 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urlpattern"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9bd5ff03aea02fa45b13a7980151fe45009af1980ba69f651ec367121a31609"
|
||||||
|
dependencies = [
|
||||||
|
"derive_more",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"unic-ucd-ident",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf-8"
|
name = "utf-8"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
@ -1146,7 +1146,7 @@
|
|||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"urls": {
|
"urls": {
|
||||||
"description": "Remote domains this capability refers to. Can use glob patterns.",
|
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
@ -33,6 +33,8 @@ json5 = { version = "0.4", optional = true }
|
|||||||
toml = { version = "0.8", features = [ "parse" ] }
|
toml = { version = "0.8", features = [ "parse" ] }
|
||||||
json-patch = "1.2"
|
json-patch = "1.2"
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
|
urlpattern = "0.2"
|
||||||
|
regex = "1"
|
||||||
walkdir = { version = "2", optional = true }
|
walkdir = { version = "2", optional = true }
|
||||||
memchr = "2"
|
memchr = "2"
|
||||||
semver = "1"
|
semver = "1"
|
||||||
|
@ -98,7 +98,7 @@ fn default_platforms() -> Vec<Target> {
|
|||||||
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
pub struct CapabilityRemote {
|
pub struct CapabilityRemote {
|
||||||
/// Remote domains this capability refers to. Can use glob patterns.
|
/// Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).
|
||||||
pub urls: Vec<String>,
|
pub urls: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,10 +4,10 @@
|
|||||||
|
|
||||||
//! Access Control List types.
|
//! Access Control List types.
|
||||||
|
|
||||||
use glob::Pattern;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::num::NonZeroU64;
|
use std::{num::NonZeroU64, str::FromStr, sync::Arc};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::platform::Target;
|
use crate::platform::Target;
|
||||||
|
|
||||||
@ -204,16 +204,60 @@ pub struct PermissionSet {
|
|||||||
pub permissions: Vec<String>,
|
pub permissions: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// UrlPattern for [`ExecutionContext::Remote`].
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct RemoteUrlPattern(Arc<urlpattern::UrlPattern>, String);
|
||||||
|
|
||||||
|
impl FromStr for RemoteUrlPattern {
|
||||||
|
type Err = urlpattern::quirks::Error;
|
||||||
|
|
||||||
|
fn from_str(s: &str) -> std::result::Result<Self, Self::Err> {
|
||||||
|
let init = urlpattern::UrlPatternInit::parse_constructor_string::<regex::Regex>(s, None)?;
|
||||||
|
let pattern = urlpattern::UrlPattern::parse(init)?;
|
||||||
|
Ok(Self(Arc::new(pattern), s.to_string()))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl RemoteUrlPattern {
|
||||||
|
#[doc(hidden)]
|
||||||
|
pub fn as_str(&self) -> &str {
|
||||||
|
&self.1
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Test if a given URL matches the pattern.
|
||||||
|
pub fn test(&self, url: &Url) -> bool {
|
||||||
|
self
|
||||||
|
.0
|
||||||
|
.test(urlpattern::UrlPatternMatchInput::Url(url.clone()))
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialEq for RemoteUrlPattern {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
self.0.protocol() == other.0.protocol()
|
||||||
|
&& self.0.username() == other.0.username()
|
||||||
|
&& self.0.password() == other.0.password()
|
||||||
|
&& self.0.hostname() == other.0.hostname()
|
||||||
|
&& self.0.port() == other.0.port()
|
||||||
|
&& self.0.pathname() == other.0.pathname()
|
||||||
|
&& self.0.search() == other.0.search()
|
||||||
|
&& self.0.hash() == other.0.hash()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for RemoteUrlPattern {}
|
||||||
|
|
||||||
/// Execution context of an IPC call.
|
/// Execution context of an IPC call.
|
||||||
#[derive(Debug, Default, Clone, Eq, PartialEq, PartialOrd, Ord, Hash)]
|
#[derive(Debug, Default, Clone, Eq, PartialEq)]
|
||||||
pub enum ExecutionContext {
|
pub enum ExecutionContext {
|
||||||
/// A local URL is used (the Tauri app URL).
|
/// A local URL is used (the Tauri app URL).
|
||||||
#[default]
|
#[default]
|
||||||
Local,
|
Local,
|
||||||
/// Remote URL is tring to use the IPC.
|
/// Remote URL is tring to use the IPC.
|
||||||
Remote {
|
Remote {
|
||||||
/// The URL trying to access the IPC (glob pattern).
|
/// The URL trying to access the IPC (URL pattern).
|
||||||
url: Pattern,
|
url: RemoteUrlPattern,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
|
|
||||||
use std::{collections::BTreeMap, fmt};
|
use std::{collections::BTreeMap, fmt};
|
||||||
|
|
||||||
use glob::Pattern;
|
|
||||||
|
|
||||||
use crate::platform::Target;
|
use crate::platform::Target;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -292,8 +290,9 @@ fn resolve_command(
|
|||||||
if let Some(remote) = &capability.remote {
|
if let Some(remote) = &capability.remote {
|
||||||
contexts.extend(remote.urls.iter().map(|url| {
|
contexts.extend(remote.urls.iter().map(|url| {
|
||||||
ExecutionContext::Remote {
|
ExecutionContext::Remote {
|
||||||
url: Pattern::new(url)
|
url: url
|
||||||
.unwrap_or_else(|e| panic!("invalid glob pattern for remote URL {url}: {e}")),
|
.parse()
|
||||||
|
.unwrap_or_else(|e| panic!("invalid URL pattern for remote URL {url}: {e}")),
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
@ -64,6 +64,7 @@ reqwest = { version = "0.11", default-features = false, features = [ "json", "st
|
|||||||
bytes = { version = "1", features = [ "serde" ] }
|
bytes = { version = "1", features = [ "serde" ] }
|
||||||
raw-window-handle = "0.6"
|
raw-window-handle = "0.6"
|
||||||
glob = "0.3"
|
glob = "0.3"
|
||||||
|
urlpattern = "0.2"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
data-url = { version = "0.3", optional = true }
|
data-url = { version = "0.3", optional = true }
|
||||||
serialize-to-javascript = "=0.1.1"
|
serialize-to-javascript = "=0.1.1"
|
||||||
|
@ -20,6 +20,8 @@ use tauri_utils::acl::{
|
|||||||
ExecutionContext, Scopes,
|
ExecutionContext, Scopes,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
use url::Url;
|
||||||
|
|
||||||
use crate::{ipc::InvokeError, sealed::ManagerBase, Runtime};
|
use crate::{ipc::InvokeError, sealed::ManagerBase, Runtime};
|
||||||
use crate::{AppHandle, Manager};
|
use crate::{AppHandle, Manager};
|
||||||
|
|
||||||
@ -40,7 +42,7 @@ pub enum Origin {
|
|||||||
/// Remote origin.
|
/// Remote origin.
|
||||||
Remote {
|
Remote {
|
||||||
/// Remote URL.
|
/// Remote URL.
|
||||||
url: String,
|
url: Url,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,7 +60,7 @@ impl Origin {
|
|||||||
match (self, context) {
|
match (self, context) {
|
||||||
(Self::Local, ExecutionContext::Local) => true,
|
(Self::Local, ExecutionContext::Local) => true,
|
||||||
(Self::Remote { url }, ExecutionContext::Remote { url: url_pattern }) => {
|
(Self::Remote { url }, ExecutionContext::Remote { url: url_pattern }) => {
|
||||||
url_pattern.matches(url)
|
url_pattern.test(url)
|
||||||
}
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
@ -816,44 +818,7 @@ mod tests {
|
|||||||
let resolved_cmd = vec![ResolvedCommand {
|
let resolved_cmd = vec![ResolvedCommand {
|
||||||
windows: vec![Pattern::new(window).unwrap()],
|
windows: vec![Pattern::new(window).unwrap()],
|
||||||
context: ExecutionContext::Remote {
|
context: ExecutionContext::Remote {
|
||||||
url: Pattern::new(url).unwrap(),
|
url: url.parse().unwrap(),
|
||||||
},
|
|
||||||
..Default::default()
|
|
||||||
}];
|
|
||||||
let allowed_commands = [(command.to_string(), resolved_cmd.clone())]
|
|
||||||
.into_iter()
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
let authority = RuntimeAuthority::new(
|
|
||||||
Default::default(),
|
|
||||||
Resolved {
|
|
||||||
allowed_commands,
|
|
||||||
..Default::default()
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(
|
|
||||||
authority.resolve_access(
|
|
||||||
command,
|
|
||||||
window,
|
|
||||||
webview,
|
|
||||||
&Origin::Remote { url: url.into() }
|
|
||||||
),
|
|
||||||
Some(resolved_cmd)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn remote_domain_glob_pattern_matches() {
|
|
||||||
let url = "http://tauri.*";
|
|
||||||
let command = "my-command";
|
|
||||||
let window = "main";
|
|
||||||
let webview = "main";
|
|
||||||
|
|
||||||
let resolved_cmd = vec![ResolvedCommand {
|
|
||||||
windows: vec![Pattern::new(window).unwrap()],
|
|
||||||
context: ExecutionContext::Remote {
|
|
||||||
url: Pattern::new(url).unwrap(),
|
|
||||||
},
|
},
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}];
|
}];
|
||||||
@ -875,7 +840,46 @@ mod tests {
|
|||||||
window,
|
window,
|
||||||
webview,
|
webview,
|
||||||
&Origin::Remote {
|
&Origin::Remote {
|
||||||
url: url.replace('*', "studio")
|
url: url.parse().unwrap()
|
||||||
|
}
|
||||||
|
),
|
||||||
|
Some(resolved_cmd)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn remote_domain_glob_pattern_matches() {
|
||||||
|
let url = "http://tauri.*";
|
||||||
|
let command = "my-command";
|
||||||
|
let window = "main";
|
||||||
|
let webview = "main";
|
||||||
|
|
||||||
|
let resolved_cmd = vec![ResolvedCommand {
|
||||||
|
windows: vec![Pattern::new(window).unwrap()],
|
||||||
|
context: ExecutionContext::Remote {
|
||||||
|
url: url.parse().unwrap(),
|
||||||
|
},
|
||||||
|
..Default::default()
|
||||||
|
}];
|
||||||
|
let allowed_commands = [(command.to_string(), resolved_cmd.clone())]
|
||||||
|
.into_iter()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let authority = RuntimeAuthority::new(
|
||||||
|
Default::default(),
|
||||||
|
Resolved {
|
||||||
|
allowed_commands,
|
||||||
|
..Default::default()
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
authority.resolve_access(
|
||||||
|
command,
|
||||||
|
window,
|
||||||
|
webview,
|
||||||
|
&Origin::Remote {
|
||||||
|
url: url.replace('*', "studio").parse().unwrap()
|
||||||
}
|
}
|
||||||
),
|
),
|
||||||
Some(resolved_cmd)
|
Some(resolved_cmd)
|
||||||
@ -908,7 +912,7 @@ mod tests {
|
|||||||
window,
|
window,
|
||||||
webview,
|
webview,
|
||||||
&Origin::Remote {
|
&Origin::Remote {
|
||||||
url: "https://tauri.app".into()
|
url: "https://tauri.app".parse().unwrap()
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.is_none());
|
.is_none());
|
||||||
|
@ -1137,7 +1137,7 @@ fn main() {
|
|||||||
Origin::Local
|
Origin::Local
|
||||||
} else {
|
} else {
|
||||||
Origin::Remote {
|
Origin::Remote {
|
||||||
url: current_url.to_string(),
|
url: current_url.clone(),
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
let (resolved_acl, has_app_acl_manifest) = {
|
let (resolved_acl, has_app_acl_manifest) = {
|
||||||
|
@ -7,63 +7,139 @@ Resolved {
|
|||||||
"plugin:fs|read_dir": [
|
"plugin:fs|read_dir": [
|
||||||
ResolvedCommand {
|
ResolvedCommand {
|
||||||
context: Remote {
|
context: Remote {
|
||||||
url: Pattern {
|
url: RemoteUrlPattern(
|
||||||
original: "https://tauri.app",
|
UrlPattern {
|
||||||
tokens: [
|
protocol: Component {
|
||||||
Char(
|
pattern_string: "https",
|
||||||
'h',
|
regexp: Ok(
|
||||||
),
|
Regex(
|
||||||
Char(
|
"^https$",
|
||||||
't',
|
),
|
||||||
),
|
),
|
||||||
Char(
|
group_name_list: [],
|
||||||
't',
|
matcher: Matcher {
|
||||||
),
|
prefix: "",
|
||||||
Char(
|
suffix: "",
|
||||||
'p',
|
inner: Literal {
|
||||||
),
|
literal: "https",
|
||||||
Char(
|
},
|
||||||
's',
|
},
|
||||||
),
|
},
|
||||||
Char(
|
username: Component {
|
||||||
':',
|
pattern_string: "",
|
||||||
),
|
regexp: Ok(
|
||||||
Char(
|
Regex(
|
||||||
'/',
|
"^$",
|
||||||
),
|
),
|
||||||
Char(
|
),
|
||||||
'/',
|
group_name_list: [],
|
||||||
),
|
matcher: Matcher {
|
||||||
Char(
|
prefix: "",
|
||||||
't',
|
suffix: "",
|
||||||
),
|
inner: Literal {
|
||||||
Char(
|
literal: "",
|
||||||
'a',
|
},
|
||||||
),
|
},
|
||||||
Char(
|
},
|
||||||
'u',
|
password: Component {
|
||||||
),
|
pattern_string: "",
|
||||||
Char(
|
regexp: Ok(
|
||||||
'r',
|
Regex(
|
||||||
),
|
"^$",
|
||||||
Char(
|
),
|
||||||
'i',
|
),
|
||||||
),
|
group_name_list: [],
|
||||||
Char(
|
matcher: Matcher {
|
||||||
'.',
|
prefix: "",
|
||||||
),
|
suffix: "",
|
||||||
Char(
|
inner: Literal {
|
||||||
'a',
|
literal: "",
|
||||||
),
|
},
|
||||||
Char(
|
},
|
||||||
'p',
|
},
|
||||||
),
|
hostname: Component {
|
||||||
Char(
|
pattern_string: "tauri.app",
|
||||||
'p',
|
regexp: Ok(
|
||||||
),
|
Regex(
|
||||||
],
|
"^tauri\\.app$",
|
||||||
is_recursive: false,
|
),
|
||||||
},
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "tauri.app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
port: Component {
|
||||||
|
pattern_string: "",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pathname: Component {
|
||||||
|
pattern_string: "/",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^/$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
search: Component {
|
||||||
|
pattern_string: "",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hash: Component {
|
||||||
|
pattern_string: "",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"https://tauri.app",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
windows: [
|
windows: [
|
||||||
Pattern {
|
Pattern {
|
||||||
@ -92,63 +168,139 @@ Resolved {
|
|||||||
"plugin:fs|read_file": [
|
"plugin:fs|read_file": [
|
||||||
ResolvedCommand {
|
ResolvedCommand {
|
||||||
context: Remote {
|
context: Remote {
|
||||||
url: Pattern {
|
url: RemoteUrlPattern(
|
||||||
original: "https://tauri.app",
|
UrlPattern {
|
||||||
tokens: [
|
protocol: Component {
|
||||||
Char(
|
pattern_string: "https",
|
||||||
'h',
|
regexp: Ok(
|
||||||
),
|
Regex(
|
||||||
Char(
|
"^https$",
|
||||||
't',
|
),
|
||||||
),
|
),
|
||||||
Char(
|
group_name_list: [],
|
||||||
't',
|
matcher: Matcher {
|
||||||
),
|
prefix: "",
|
||||||
Char(
|
suffix: "",
|
||||||
'p',
|
inner: Literal {
|
||||||
),
|
literal: "https",
|
||||||
Char(
|
},
|
||||||
's',
|
},
|
||||||
),
|
},
|
||||||
Char(
|
username: Component {
|
||||||
':',
|
pattern_string: "",
|
||||||
),
|
regexp: Ok(
|
||||||
Char(
|
Regex(
|
||||||
'/',
|
"^$",
|
||||||
),
|
),
|
||||||
Char(
|
),
|
||||||
'/',
|
group_name_list: [],
|
||||||
),
|
matcher: Matcher {
|
||||||
Char(
|
prefix: "",
|
||||||
't',
|
suffix: "",
|
||||||
),
|
inner: Literal {
|
||||||
Char(
|
literal: "",
|
||||||
'a',
|
},
|
||||||
),
|
},
|
||||||
Char(
|
},
|
||||||
'u',
|
password: Component {
|
||||||
),
|
pattern_string: "",
|
||||||
Char(
|
regexp: Ok(
|
||||||
'r',
|
Regex(
|
||||||
),
|
"^$",
|
||||||
Char(
|
),
|
||||||
'i',
|
),
|
||||||
),
|
group_name_list: [],
|
||||||
Char(
|
matcher: Matcher {
|
||||||
'.',
|
prefix: "",
|
||||||
),
|
suffix: "",
|
||||||
Char(
|
inner: Literal {
|
||||||
'a',
|
literal: "",
|
||||||
),
|
},
|
||||||
Char(
|
},
|
||||||
'p',
|
},
|
||||||
),
|
hostname: Component {
|
||||||
Char(
|
pattern_string: "tauri.app",
|
||||||
'p',
|
regexp: Ok(
|
||||||
),
|
Regex(
|
||||||
],
|
"^tauri\\.app$",
|
||||||
is_recursive: false,
|
),
|
||||||
},
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "tauri.app",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
port: Component {
|
||||||
|
pattern_string: "",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
pathname: Component {
|
||||||
|
pattern_string: "/",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^/$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "/",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
search: Component {
|
||||||
|
pattern_string: "",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
hash: Component {
|
||||||
|
pattern_string: "",
|
||||||
|
regexp: Ok(
|
||||||
|
Regex(
|
||||||
|
"^$",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
group_name_list: [],
|
||||||
|
matcher: Matcher {
|
||||||
|
prefix: "",
|
||||||
|
suffix: "",
|
||||||
|
inner: Literal {
|
||||||
|
literal: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
"https://tauri.app",
|
||||||
|
),
|
||||||
},
|
},
|
||||||
windows: [
|
windows: [
|
||||||
Pattern {
|
Pattern {
|
||||||
|
56
tooling/cli/Cargo.lock
generated
56
tooling/cli/Cargo.lock
generated
@ -4936,6 +4936,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"memchr",
|
"memchr",
|
||||||
"phf 0.11.2",
|
"phf 0.11.2",
|
||||||
|
"regex",
|
||||||
"schemars",
|
"schemars",
|
||||||
"semver",
|
"semver",
|
||||||
"serde",
|
"serde",
|
||||||
@ -4945,6 +4946,7 @@ dependencies = [
|
|||||||
"thiserror",
|
"thiserror",
|
||||||
"toml 0.8.10",
|
"toml 0.8.10",
|
||||||
"url",
|
"url",
|
||||||
|
"urlpattern",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -5359,6 +5361,47 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-char-property"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a8c57a407d9b6fa02b4795eb81c5b6652060a15a7903ea981f3d723e6c0be221"
|
||||||
|
dependencies = [
|
||||||
|
"unic-char-range",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-char-range"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0398022d5f700414f6b899e10b8348231abf9173fa93144cbc1a43b9793c1fbc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-common"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "80d7ff825a6a654ee85a63e80f92f054f904f21e7d12da4e22f9834a4aaa35bc"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-ucd-ident"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e230a37c0381caa9219d67cf063aa3a375ffed5bf541a452db16e744bdab6987"
|
||||||
|
dependencies = [
|
||||||
|
"unic-char-property",
|
||||||
|
"unic-char-range",
|
||||||
|
"unic-ucd-version",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "unic-ucd-version"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96bd2f2237fe450fcd0a1d2f5f4e91711124f7857ba2e964247776ebeeb7b0c4"
|
||||||
|
dependencies = [
|
||||||
|
"unic-common",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.15"
|
version = "0.3.15"
|
||||||
@ -5475,6 +5518,19 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "urlpattern"
|
||||||
|
version = "0.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f9bd5ff03aea02fa45b13a7980151fe45009af1980ba69f651ec367121a31609"
|
||||||
|
dependencies = [
|
||||||
|
"derive_more",
|
||||||
|
"regex",
|
||||||
|
"serde",
|
||||||
|
"unic-ucd-ident",
|
||||||
|
"url",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "usvg"
|
name = "usvg"
|
||||||
version = "0.40.0"
|
version = "0.40.0"
|
||||||
|
@ -1146,7 +1146,7 @@
|
|||||||
],
|
],
|
||||||
"properties": {
|
"properties": {
|
||||||
"urls": {
|
"urls": {
|
||||||
"description": "Remote domains this capability refers to. Can use glob patterns.",
|
"description": "Remote domains this capability refers to using the [URLPattern standard](https://urlpattern.spec.whatwg.org/).",
|
||||||
"type": "array",
|
"type": "array",
|
||||||
"items": {
|
"items": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
|
Loading…
Reference in New Issue
Block a user