mirror of
https://github.com/tauri-apps/tauri.git
synced 2026-02-06 13:17:02 +00:00
refactor(core): split allowlist configuration per module (#1263)
* refactor(core): split allowlist configuration per module * fix: build with all features * fix(cli): run fmt * fix(core): run fmt
This commit is contained in:
parent
75eaaf0132
commit
e0be59ea26
5
.changes/refactor-allowlist.md
Normal file
5
.changes/refactor-allowlist.md
Normal file
@ -0,0 +1,5 @@
|
||||
---
|
||||
"tauri": minor
|
||||
---
|
||||
|
||||
The `allowlist` configuration now has one object per module.
|
||||
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@ -78,7 +78,7 @@ The code for the bundler is located in `[Tauri repo root]/cli/tauri-bundler`. Bu
|
||||
|
||||
### Developing Tauri Core
|
||||
|
||||
The code for Tauri core is located in `[Tauri repo root]/tauri`. The easiest way to test your changes is to use the `[Tauri repo root]/tauri/examples/communication` app. It automatically rebuilds and uses your local codebase. Just run `yarn tauri build` or `yarn tauri dev` in the communication app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH", features = [ "all-api", "cli" ] }`, where `PATH` is the relative path to `[Tauri repo root]/tauri`.
|
||||
The code for Tauri core is located in `[Tauri repo root]/tauri`. The easiest way to test your changes is to use the `[Tauri repo root]/tauri/examples/communication` app. It automatically rebuilds and uses your local codebase. Just run `yarn tauri build` or `yarn tauri dev` in the communication app directory after making changes to test them out. To use your local changes in another project, edit its `src-tauri/Cargo.toml` file so that the `tauri` key looks like `tauri = { path = "PATH", features = [ "api-all", "cli" ] }`, where `PATH` is the relative path to `[Tauri repo root]/tauri`.
|
||||
|
||||
## Financial Contribution
|
||||
|
||||
|
||||
2
.github/workflows/core-lint-fmt.yml
vendored
2
.github/workflows/core-lint-fmt.yml
vendored
@ -62,7 +62,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
feature: [embedded-server, all-api]
|
||||
feature: [embedded-server, api-all]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
7
cli/core/Cargo.lock
generated
7
cli/core/Cargo.lock
generated
@ -329,12 +329,6 @@ version = "0.4.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28b9d6de7f49e22cf97ad17fc4036ece69300032f45f78f30b4a4482cdc3f4a6"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.1"
|
||||
@ -1999,7 +1993,6 @@ dependencies = [
|
||||
"anyhow",
|
||||
"clap 3.0.0-beta.2",
|
||||
"colored",
|
||||
"convert_case",
|
||||
"json-patch",
|
||||
"notify",
|
||||
"once_cell",
|
||||
|
||||
@ -21,7 +21,6 @@ serde_json = "1.0"
|
||||
notify = "4.0"
|
||||
shared_child = "0.3"
|
||||
toml_edit = "0.2"
|
||||
convert_case = "0.4"
|
||||
json-patch = "0.2"
|
||||
schemars = "0.8"
|
||||
valico = "3.5"
|
||||
|
||||
@ -250,6 +250,232 @@ pub struct SecurityConfig {
|
||||
csp: Option<String>,
|
||||
}
|
||||
|
||||
trait Allowlist {
|
||||
fn to_features(&self) -> Vec<&str>;
|
||||
}
|
||||
|
||||
macro_rules! check_feature {
|
||||
($self:ident, $features:ident, $flag:ident, $feature_name: expr) => {
|
||||
if $self.$flag {
|
||||
$features.push($feature_name)
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct FsAllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
#[serde(default)]
|
||||
read_text_file: bool,
|
||||
#[serde(default)]
|
||||
read_binary_file: bool,
|
||||
#[serde(default)]
|
||||
write_file: bool,
|
||||
#[serde(default)]
|
||||
write_binary_file: bool,
|
||||
#[serde(default)]
|
||||
read_dir: bool,
|
||||
#[serde(default)]
|
||||
copy_file: bool,
|
||||
#[serde(default)]
|
||||
create_dir: bool,
|
||||
#[serde(default)]
|
||||
remove_dir: bool,
|
||||
#[serde(default)]
|
||||
remove_file: bool,
|
||||
#[serde(default)]
|
||||
rename_file: bool,
|
||||
#[serde(default)]
|
||||
path: bool,
|
||||
}
|
||||
|
||||
impl Allowlist for FsAllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["fs-all"]
|
||||
} else {
|
||||
let mut features = Vec::new();
|
||||
check_feature!(self, features, read_text_file, "fs-read-text-file");
|
||||
check_feature!(self, features, read_binary_file, "fs-read-binary-file");
|
||||
check_feature!(self, features, write_file, "fs-write-file");
|
||||
check_feature!(self, features, write_binary_file, "fs-write-binary-file");
|
||||
check_feature!(self, features, read_dir, "fs-read-dir");
|
||||
check_feature!(self, features, copy_file, "fs-copy-file");
|
||||
check_feature!(self, features, create_dir, "fs-create-dir");
|
||||
check_feature!(self, features, remove_dir, "fs-remove-dir");
|
||||
check_feature!(self, features, remove_file, "fs-remove-file");
|
||||
check_feature!(self, features, rename_file, "fs-rename-file");
|
||||
check_feature!(self, features, path, "fs-path");
|
||||
features
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct WindowAllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
#[serde(default)]
|
||||
create: bool,
|
||||
}
|
||||
|
||||
impl Allowlist for WindowAllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["window-all"]
|
||||
} else {
|
||||
let mut features = Vec::new();
|
||||
check_feature!(self, features, create, "window-create");
|
||||
features
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct ShellAllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
#[serde(default)]
|
||||
execute: bool,
|
||||
#[serde(default)]
|
||||
open: bool,
|
||||
}
|
||||
|
||||
impl Allowlist for ShellAllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["shell-all"]
|
||||
} else {
|
||||
let mut features = Vec::new();
|
||||
check_feature!(self, features, execute, "shell-execute");
|
||||
check_feature!(self, features, open, "shell-open");
|
||||
features
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct DialogAllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
#[serde(default)]
|
||||
open: bool,
|
||||
#[serde(default)]
|
||||
save: bool,
|
||||
}
|
||||
|
||||
impl Allowlist for DialogAllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["dialog-all"]
|
||||
} else {
|
||||
let mut features = Vec::new();
|
||||
check_feature!(self, features, open, "dialog-open");
|
||||
check_feature!(self, features, save, "dialog-save");
|
||||
features
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct HttpAllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
#[serde(default)]
|
||||
request: bool,
|
||||
}
|
||||
|
||||
impl Allowlist for HttpAllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["http-all"]
|
||||
} else {
|
||||
let mut features = Vec::new();
|
||||
check_feature!(self, features, request, "http-request");
|
||||
features
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct NotificationAllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
}
|
||||
|
||||
impl Allowlist for NotificationAllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["notification-all"]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct GlobalShortcutAllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
}
|
||||
|
||||
impl Allowlist for GlobalShortcutAllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["global-shortcut-all"]
|
||||
} else {
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
struct AllowlistConfig {
|
||||
#[serde(default)]
|
||||
all: bool,
|
||||
#[serde(default)]
|
||||
fs: FsAllowlistConfig,
|
||||
#[serde(default)]
|
||||
window: WindowAllowlistConfig,
|
||||
#[serde(default)]
|
||||
shell: ShellAllowlistConfig,
|
||||
#[serde(default)]
|
||||
dialog: DialogAllowlistConfig,
|
||||
#[serde(default)]
|
||||
http: HttpAllowlistConfig,
|
||||
#[serde(default)]
|
||||
notification: NotificationAllowlistConfig,
|
||||
#[serde(default)]
|
||||
global_shortcut: GlobalShortcutAllowlistConfig,
|
||||
}
|
||||
|
||||
impl Allowlist for AllowlistConfig {
|
||||
fn to_features(&self) -> Vec<&str> {
|
||||
if self.all {
|
||||
vec!["api-all"]
|
||||
} else {
|
||||
let mut features = Vec::new();
|
||||
features.extend(self.fs.to_features());
|
||||
features.extend(self.window.to_features());
|
||||
features.extend(self.shell.to_features());
|
||||
features.extend(self.dialog.to_features());
|
||||
features.extend(self.http.to_features());
|
||||
features.extend(self.notification.to_features());
|
||||
features.extend(self.global_shortcut.to_features());
|
||||
features
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The Tauri configuration object.
|
||||
#[derive(Debug, Default, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
@ -265,10 +491,17 @@ pub struct TauriConfig {
|
||||
#[serde(default)]
|
||||
pub bundle: BundleConfig,
|
||||
#[serde(default)]
|
||||
pub allowlist: HashMap<String, bool>,
|
||||
allowlist: AllowlistConfig,
|
||||
pub security: Option<SecurityConfig>,
|
||||
}
|
||||
|
||||
impl TauriConfig {
|
||||
#[allow(dead_code)]
|
||||
pub fn features(&self) -> Vec<&str> {
|
||||
self.allowlist.to_features()
|
||||
}
|
||||
}
|
||||
|
||||
/// The Build configuration object.
|
||||
#[derive(Debug, PartialEq, Clone, Deserialize, Serialize, JsonSchema)]
|
||||
#[serde(rename_all = "camelCase", deny_unknown_fields)]
|
||||
|
||||
@ -31,7 +31,47 @@
|
||||
"tauri": {
|
||||
"description": "The Tauri configuration.",
|
||||
"default": {
|
||||
"allowlist": {},
|
||||
"allowlist": {
|
||||
"all": false,
|
||||
"dialog": {
|
||||
"all": false,
|
||||
"open": false,
|
||||
"save": false
|
||||
},
|
||||
"fs": {
|
||||
"all": false,
|
||||
"copyFile": false,
|
||||
"createDir": false,
|
||||
"path": false,
|
||||
"readBinaryFile": false,
|
||||
"readDir": false,
|
||||
"readTextFile": false,
|
||||
"removeDir": false,
|
||||
"removeFile": false,
|
||||
"renameFile": false,
|
||||
"writeBinaryFile": false,
|
||||
"writeFile": false
|
||||
},
|
||||
"globalShortcut": {
|
||||
"all": false
|
||||
},
|
||||
"http": {
|
||||
"all": false,
|
||||
"request": false
|
||||
},
|
||||
"notification": {
|
||||
"all": false
|
||||
},
|
||||
"shell": {
|
||||
"all": false,
|
||||
"execute": false,
|
||||
"open": false
|
||||
},
|
||||
"window": {
|
||||
"all": false,
|
||||
"create": false
|
||||
}
|
||||
},
|
||||
"bundle": {
|
||||
"active": false,
|
||||
"category": null,
|
||||
@ -76,6 +116,103 @@
|
||||
},
|
||||
"additionalProperties": false,
|
||||
"definitions": {
|
||||
"AllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"dialog": {
|
||||
"default": {
|
||||
"all": false,
|
||||
"open": false,
|
||||
"save": false
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/DialogAllowlistConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"fs": {
|
||||
"default": {
|
||||
"all": false,
|
||||
"copyFile": false,
|
||||
"createDir": false,
|
||||
"path": false,
|
||||
"readBinaryFile": false,
|
||||
"readDir": false,
|
||||
"readTextFile": false,
|
||||
"removeDir": false,
|
||||
"removeFile": false,
|
||||
"renameFile": false,
|
||||
"writeBinaryFile": false,
|
||||
"writeFile": false
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/FsAllowlistConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"globalShortcut": {
|
||||
"default": {
|
||||
"all": false
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/GlobalShortcutAllowlistConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"http": {
|
||||
"default": {
|
||||
"all": false,
|
||||
"request": false
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/HttpAllowlistConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"notification": {
|
||||
"default": {
|
||||
"all": false
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/NotificationAllowlistConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"shell": {
|
||||
"default": {
|
||||
"all": false,
|
||||
"execute": false,
|
||||
"open": false
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/ShellAllowlistConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"window": {
|
||||
"default": {
|
||||
"all": false,
|
||||
"create": false
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/WindowAllowlistConfig"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"BuildConfig": {
|
||||
"description": "The Build configuration object.",
|
||||
"type": "object",
|
||||
@ -524,6 +661,24 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"DialogAllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"open": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"save": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"EmbeddedServerConfig": {
|
||||
"description": "The embeddedServer configuration object.",
|
||||
"type": "object",
|
||||
@ -556,6 +711,94 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"FsAllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"copyFile": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"createDir": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"path": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"readBinaryFile": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"readDir": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"readTextFile": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"removeDir": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"removeFile": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"renameFile": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"writeBinaryFile": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"writeFile": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"GlobalShortcutAllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"HttpAllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"request": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"NotificationAllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"OsxConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@ -619,16 +862,75 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"ShellAllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"execute": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"open": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"TauriConfig": {
|
||||
"description": "The Tauri configuration object.",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"allowlist": {
|
||||
"default": {},
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
"type": "boolean"
|
||||
}
|
||||
"default": {
|
||||
"all": false,
|
||||
"dialog": {
|
||||
"all": false,
|
||||
"open": false,
|
||||
"save": false
|
||||
},
|
||||
"fs": {
|
||||
"all": false,
|
||||
"copyFile": false,
|
||||
"createDir": false,
|
||||
"path": false,
|
||||
"readBinaryFile": false,
|
||||
"readDir": false,
|
||||
"readTextFile": false,
|
||||
"removeDir": false,
|
||||
"removeFile": false,
|
||||
"renameFile": false,
|
||||
"writeBinaryFile": false,
|
||||
"writeFile": false
|
||||
},
|
||||
"globalShortcut": {
|
||||
"all": false
|
||||
},
|
||||
"http": {
|
||||
"all": false,
|
||||
"request": false
|
||||
},
|
||||
"notification": {
|
||||
"all": false
|
||||
},
|
||||
"shell": {
|
||||
"all": false,
|
||||
"execute": false,
|
||||
"open": false
|
||||
},
|
||||
"window": {
|
||||
"all": false,
|
||||
"create": false
|
||||
}
|
||||
},
|
||||
"allOf": [
|
||||
{
|
||||
"$ref": "#/definitions/AllowlistConfig"
|
||||
}
|
||||
]
|
||||
},
|
||||
"bundle": {
|
||||
"description": "The bundler configuration.",
|
||||
@ -708,6 +1010,20 @@
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"WindowAllowlistConfig": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"all": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
},
|
||||
"create": {
|
||||
"default": false,
|
||||
"type": "boolean"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"WindowConfig": {
|
||||
"description": "The window configuration object.",
|
||||
"type": "object",
|
||||
|
||||
@ -1,6 +1,5 @@
|
||||
use super::{app_paths::tauri_dir, config::ConfigHandle};
|
||||
|
||||
use convert_case::{Case, Casing};
|
||||
use toml_edit::{Array, Document, Value};
|
||||
|
||||
use std::{
|
||||
@ -27,21 +26,13 @@ pub fn rewrite_manifest(config: ConfigHandle) -> crate::Result<()> {
|
||||
let config = config_guard.as_ref().unwrap();
|
||||
|
||||
if let Some(tauri) = tauri {
|
||||
let mut features: Array = Default::default();
|
||||
|
||||
let allowlist = &config.tauri.allowlist;
|
||||
if *allowlist.get("all").unwrap_or(&false) {
|
||||
features.push("all-api".to_string()).unwrap();
|
||||
} else {
|
||||
for (feature, enabled) in allowlist.iter() {
|
||||
if *enabled {
|
||||
features.push(feature.to_case(Case::Kebab)).unwrap();
|
||||
}
|
||||
}
|
||||
let allowlist_features = config.tauri.features();
|
||||
let mut features = Array::default();
|
||||
for feature in allowlist_features {
|
||||
features.push(feature).unwrap();
|
||||
}
|
||||
|
||||
if config.tauri.cli.is_some() {
|
||||
features.push("cli".to_string()).unwrap();
|
||||
features.push("cli").unwrap();
|
||||
}
|
||||
|
||||
match tauri {
|
||||
|
||||
@ -24,7 +24,7 @@ icon = [
|
||||
serde_json = "1.0.62"
|
||||
serde = "1.0"
|
||||
serde_derive = "1.0"
|
||||
tauri = { path = "../../../../../../../tauri", features =["all-api"]}
|
||||
tauri = { path = "../../../../../../../tauri", features =["api-all"]}
|
||||
|
||||
[features]
|
||||
embedded-server = [ "tauri/embedded-server" ]
|
||||
|
||||
@ -15,7 +15,7 @@ edition = "2018"
|
||||
exclude = [ "test/fixture/**" ]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
features = [ "all-api" ]
|
||||
features = [ "api-all" ]
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
@ -44,49 +44,52 @@ cfg_aliases = "0.1.1"
|
||||
[dev-dependencies]
|
||||
proptest = "0.10.1"
|
||||
serde_json = "1.0"
|
||||
tauri = { path = ".", features = [ "all-api" ] }
|
||||
tauri = { path = ".", features = [ "api-all" ] }
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
|
||||
[features]
|
||||
cli = [ "tauri-api/cli" ]
|
||||
embedded-server = [ "tiny_http" ]
|
||||
all-api = [ "tauri-api/notification", "tauri-api/global-shortcut" ]
|
||||
api-all = [ "tauri-api/notification", "tauri-api/global-shortcut" ]
|
||||
updater = [ ]
|
||||
|
||||
# FS
|
||||
read-text-file = [ ]
|
||||
read-binary-file = [ ]
|
||||
write-file = [ ]
|
||||
write-binary-file = [ ]
|
||||
read-dir = [ ]
|
||||
copy-file = [ ]
|
||||
create-dir = [ ]
|
||||
remove-dir = [ ]
|
||||
remove-file = [ ]
|
||||
rename-file = [ ]
|
||||
path-api = [ ]
|
||||
event = [ ]
|
||||
fs-all = [ ]
|
||||
fs-read-text-file = [ ]
|
||||
fs-read-binary-file = [ ]
|
||||
fs-write-file = [ ]
|
||||
fs-write-binary-file = [ ]
|
||||
fs-read-dir = [ ]
|
||||
fs-copy-file = [ ]
|
||||
fs-create-dir = [ ]
|
||||
fs-remove-dir = [ ]
|
||||
fs-remove-file = [ ]
|
||||
fs-rename-file = [ ]
|
||||
fs-path-api = [ ]
|
||||
|
||||
# window
|
||||
window = [ ]
|
||||
create-window = [ ]
|
||||
window-all = [ ]
|
||||
window-create = [ ]
|
||||
|
||||
#shell
|
||||
execute = [ ]
|
||||
open = [ ]
|
||||
shell-all = [ ]
|
||||
shell-execute = [ ]
|
||||
shell-open = [ ]
|
||||
|
||||
# dialog
|
||||
open-dialog = [ ]
|
||||
save-dialog = [ ]
|
||||
dialog-all = [ ]
|
||||
dialog-open = [ ]
|
||||
dialog-save = [ ]
|
||||
|
||||
# HTTP
|
||||
http-all = [ ]
|
||||
http-request = [ ]
|
||||
|
||||
# notification
|
||||
notification = [ "tauri-api/notification" ]
|
||||
notification-all = [ "tauri-api/notification" ]
|
||||
|
||||
# global shortcut
|
||||
global-shortcut = [ "tauri-api/global-shortcut" ]
|
||||
global-shortcut-all = [ "tauri-api/global-shortcut" ]
|
||||
|
||||
[[example]]
|
||||
name = "communication"
|
||||
|
||||
@ -5,45 +5,47 @@ fn main() {
|
||||
embedded_server: { feature = "embedded-server" },
|
||||
dev: { not(feature = "embedded-server") },
|
||||
|
||||
all_api: { feature = "all-api" },
|
||||
api_all: { feature = "api-all" },
|
||||
|
||||
// fs
|
||||
read_text_file: { any(all_api, feature = "read-text-file") },
|
||||
read_binary_file: { any(all_api, feature = "read-binary-file") },
|
||||
write_file: { any(all_api, feature = "write-file") },
|
||||
write_binary_file: { any(all_api, feature = "write-binary-file") },
|
||||
read_dir: { any(all_api, feature = "read-dir") },
|
||||
copy_file: { any(all_api, feature = "copy-file") },
|
||||
create_dir: { any(all_api, feature = "create_dir") },
|
||||
remove_dir: { any(all_api, feature = "remove-dir") },
|
||||
remove_file: { any(all_api, feature = "remove-file") },
|
||||
rename_file: { any(all_api, feature = "rename-file") },
|
||||
|
||||
// js path api
|
||||
path_api: { any(all_api, feature = "path-api") },
|
||||
fs_all: { any(api_all, feature = "fs-all") },
|
||||
fs_read_text_file: { any(fs_all, feature = "fs-read-text-file") },
|
||||
fs_read_binary_file: { any(fs_all, feature = "fs-read-binary-file") },
|
||||
fs_write_file: { any(fs_all, feature = "fs-write-file") },
|
||||
fs_write_binary_file: { any(fs_all, feature = "fs-write-binary-file") },
|
||||
fs_read_dir: { any(fs_all, feature = "fs-read-dir") },
|
||||
fs_copy_file: { any(fs_all, feature = "fs-copy-file") },
|
||||
fs_create_dir: { any(fs_all, feature = "fs-create_dir") },
|
||||
fs_remove_dir: { any(fs_all, feature = "fs-remove-dir") },
|
||||
fs_remove_file: { any(fs_all, feature = "fs-remove-file") },
|
||||
fs_rename_file: { any(fs_all, feature = "fs-rename-file") },
|
||||
fs_path: { any(fs_all, feature = "fs-path") },
|
||||
|
||||
// window
|
||||
window: { any(all_api, feature = "window") },
|
||||
create_window: { any(all_api, feature = "create-window") },
|
||||
window_all: { any(api_all, feature = "window-all") },
|
||||
window_create: { any(window_all, feature = "window-create") },
|
||||
|
||||
// shell
|
||||
open: { any(all_api, feature = "open") },
|
||||
execute: { any(all_api, feature = "execute") },
|
||||
shell_all: { any(api_all, feature = "shell-all") },
|
||||
shell_open: { any(shell_all, feature = "shell-open") },
|
||||
shell_execute: { any(shell_all, feature = "shell-execute") },
|
||||
|
||||
// dialog
|
||||
open_dialog: { any(all_api, feature = "open-dialog") },
|
||||
save_dialog: { any(all_api, feature = "save-dialog") },
|
||||
dialog_all: { any(api_all, feature = "dialog-all") },
|
||||
dialog_open: { any(dialog_all, feature = "dialog-open") },
|
||||
dialog_save: { any(dialog_all, feature = "dialog-save") },
|
||||
|
||||
// http
|
||||
http_request: { any(all_api, feature = "http-request") },
|
||||
http_all: { any(api_all, feature = "http-all") },
|
||||
http_request: { any(http_all, feature = "http-request") },
|
||||
|
||||
// cli
|
||||
cli: { feature = "cli" },
|
||||
|
||||
// notification
|
||||
notification: { any(all_api, feature = "notification") },
|
||||
notification_all: { any(api_all, feature = "notification-all") },
|
||||
|
||||
// global shortcut
|
||||
global_shortcut: { any(all_api, feature = "global_shortcut" )},
|
||||
global_shortcut_all: { any(api_all, feature = "global_shortcut-all") },
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ build = "src/build.rs"
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
tauri = { path = "../../..", features =["all-api", "cli"]}
|
||||
tauri = { path = "../../..", features =["api-all", "cli"]}
|
||||
|
||||
[target."cfg(windows)".build-dependencies]
|
||||
winres = "0.1"
|
||||
|
||||
@ -24,7 +24,7 @@ icon = [
|
||||
[dependencies]
|
||||
serde_json = "1.0"
|
||||
serde = { version = "1.0", features = [ "derive" ] }
|
||||
tauri = { path = "../../..", features =["all-api", "cli"]}
|
||||
tauri = { path = "../../..", features =["api-all", "cli"]}
|
||||
|
||||
[target."cfg(windows)".build-dependencies]
|
||||
winres = "0.1"
|
||||
|
||||
@ -22,7 +22,7 @@ icon = [
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
tauri = { path = "../../..", features =["all-api"]}
|
||||
tauri = { path = "../../..", features =["api-all"]}
|
||||
|
||||
[target."cfg(windows)".build-dependencies]
|
||||
winres = "0.1"
|
||||
|
||||
@ -3,12 +3,9 @@ mod dialog;
|
||||
mod event;
|
||||
#[allow(unused_imports)]
|
||||
mod file_system;
|
||||
#[cfg(global_shortcut)]
|
||||
mod global_shortcut;
|
||||
#[cfg(http_request)]
|
||||
mod http;
|
||||
mod internal;
|
||||
#[cfg(notification)]
|
||||
mod notification;
|
||||
mod shell;
|
||||
mod window;
|
||||
|
||||
@ -1,5 +1,7 @@
|
||||
#[cfg(any(dialog_open, dialog_save))]
|
||||
use crate::api::dialog::FileDialogBuilder;
|
||||
use crate::{
|
||||
api::dialog::{ask as ask_dialog, message as message_dialog, AskResponse, FileDialogBuilder},
|
||||
api::dialog::{ask as ask_dialog, message as message_dialog, AskResponse},
|
||||
app::InvokeResponse,
|
||||
};
|
||||
use serde::Deserialize;
|
||||
@ -66,16 +68,16 @@ impl Cmd {
|
||||
pub async fn run(self) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::OpenDialog { options } => {
|
||||
#[cfg(open_dialog)]
|
||||
#[cfg(dialog_open)]
|
||||
return open(options);
|
||||
#[cfg(not(open_dialog))]
|
||||
Err(crate::Error::ApiNotAllowlisted("title".to_string()));
|
||||
#[cfg(not(dialog_open))]
|
||||
return Err(crate::Error::ApiNotAllowlisted("dialog > open".to_string()));
|
||||
}
|
||||
Self::SaveDialog { options } => {
|
||||
#[cfg(save_dialog)]
|
||||
#[cfg(dialog_save)]
|
||||
return save(options);
|
||||
#[cfg(not(save_dialog))]
|
||||
Err(crate::Error::ApiNotAllowlisted("saveDialog".to_string()));
|
||||
#[cfg(not(dialog_save))]
|
||||
return Err(crate::Error::ApiNotAllowlisted("dialog > save".to_string()));
|
||||
}
|
||||
Self::MessageDialog { message } => {
|
||||
let exe = std::env::current_exe()?;
|
||||
@ -106,7 +108,7 @@ impl Cmd {
|
||||
}
|
||||
|
||||
/// Shows an open dialog.
|
||||
#[cfg(open_dialog)]
|
||||
#[cfg(dialog_open)]
|
||||
pub fn open(options: OpenDialogOptions) -> crate::Result<InvokeResponse> {
|
||||
let mut dialog_builder = FileDialogBuilder::new();
|
||||
if let Some(default_path) = options.default_path {
|
||||
@ -127,7 +129,7 @@ pub fn open(options: OpenDialogOptions) -> crate::Result<InvokeResponse> {
|
||||
}
|
||||
|
||||
/// Shows a save dialog.
|
||||
#[cfg(save_dialog)]
|
||||
#[cfg(dialog_save)]
|
||||
pub fn save(options: SaveDialogOptions) -> crate::Result<InvokeResponse> {
|
||||
let mut dialog_builder = FileDialogBuilder::new();
|
||||
if let Some(default_path) = options.default_path {
|
||||
|
||||
@ -94,15 +94,17 @@ impl Cmd {
|
||||
pub async fn run(self) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::ReadTextFile { path, options } => {
|
||||
#[cfg(read_text_file)]
|
||||
#[cfg(fs_read_text_file)]
|
||||
return read_text_file(path, options).await.map(Into::into);
|
||||
#[cfg(not(read_text_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted("readTextFile".to_string()))
|
||||
#[cfg(not(fs_read_text_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > readTextFile".to_string(),
|
||||
))
|
||||
}
|
||||
Self::ReadBinaryFile { path, options } => {
|
||||
#[cfg(read_binary_file)]
|
||||
#[cfg(fs_read_binary_file)]
|
||||
return read_binary_file(path, options).await.map(Into::into);
|
||||
#[cfg(not(read_binary_file))]
|
||||
#[cfg(not(fs_read_binary_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"readBinaryFile".to_string(),
|
||||
))
|
||||
@ -112,85 +114,95 @@ impl Cmd {
|
||||
contents,
|
||||
options,
|
||||
} => {
|
||||
#[cfg(write_file)]
|
||||
#[cfg(fs_write_file)]
|
||||
return write_file(path, contents, options).await.map(Into::into);
|
||||
#[cfg(not(write_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted("writeFile".to_string()))
|
||||
#[cfg(not(fs_write_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > writeFile".to_string(),
|
||||
))
|
||||
}
|
||||
Self::WriteBinaryFile {
|
||||
path,
|
||||
contents,
|
||||
options,
|
||||
} => {
|
||||
#[cfg(write_binary_file)]
|
||||
#[cfg(fs_write_binary_file)]
|
||||
return write_binary_file(path, contents, options)
|
||||
.await
|
||||
.map(Into::into);
|
||||
#[cfg(not(write_binary_file))]
|
||||
#[cfg(not(fs_write_binary_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"writeBinaryFile".to_string(),
|
||||
))
|
||||
}
|
||||
Self::ReadDir { path, options } => {
|
||||
#[cfg(read_dir)]
|
||||
#[cfg(fs_read_dir)]
|
||||
return read_dir(path, options).await.map(Into::into);
|
||||
#[cfg(not(read_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted("readDir".to_string()))
|
||||
#[cfg(not(fs_read_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted("fs > readDir".to_string()))
|
||||
}
|
||||
Self::CopyFile {
|
||||
source,
|
||||
destination,
|
||||
options,
|
||||
} => {
|
||||
#[cfg(copy_file)]
|
||||
#[cfg(fs_copy_file)]
|
||||
return copy_file(source, destination, options)
|
||||
.await
|
||||
.map(Into::into);
|
||||
#[cfg(not(copy_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted("copyFile".to_string()))
|
||||
#[cfg(not(fs_copy_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted("fs > copyFile".to_string()))
|
||||
}
|
||||
Self::CreateDir { path, options } => {
|
||||
#[cfg(create_dir)]
|
||||
#[cfg(fs_create_dir)]
|
||||
return create_dir(path, options).await.map(Into::into);
|
||||
#[cfg(not(create_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted("createDir".to_string()))
|
||||
#[cfg(not(fs_create_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > createDir".to_string(),
|
||||
))
|
||||
}
|
||||
Self::RemoveDir { path, options } => {
|
||||
#[cfg(remove_dir)]
|
||||
#[cfg(fs_remove_dir)]
|
||||
return remove_dir(path, options).await.map(Into::into);
|
||||
#[cfg(not(remove_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted("removeDir".to_string()))
|
||||
#[cfg(not(fs_remove_dir))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > removeDir".to_string(),
|
||||
))
|
||||
}
|
||||
Self::RemoveFile { path, options } => {
|
||||
#[cfg(remove_file)]
|
||||
#[cfg(fs_remove_file)]
|
||||
return remove_file(path, options).await.map(Into::into);
|
||||
#[cfg(not(remove_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted("removeFile".to_string()))
|
||||
#[cfg(not(fs_remove_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > removeFile".to_string(),
|
||||
))
|
||||
}
|
||||
Self::RenameFile {
|
||||
old_path,
|
||||
new_path,
|
||||
options,
|
||||
} => {
|
||||
#[cfg(rename_file)]
|
||||
#[cfg(fs_rename_file)]
|
||||
return rename_file(old_path, new_path, options)
|
||||
.await
|
||||
.map(Into::into);
|
||||
#[cfg(not(rename_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted("renameFile".to_string()))
|
||||
#[cfg(not(fs_rename_file))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"fs > renameFile".to_string(),
|
||||
))
|
||||
}
|
||||
Self::ResolvePath { path, directory } => {
|
||||
#[cfg(path_api)]
|
||||
#[cfg(fs_path)]
|
||||
return resolve_path_handler(path, directory).await.map(Into::into);
|
||||
#[cfg(not(path_api))]
|
||||
Err(crate::Error::ApiNotAllowlisted("pathApi".to_string()))
|
||||
#[cfg(not(fs_path))]
|
||||
Err(crate::Error::ApiNotAllowlisted("fs > pathApi".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Reads a directory.
|
||||
#[cfg(read_dir)]
|
||||
#[cfg(fs_read_dir)]
|
||||
pub async fn read_dir(
|
||||
path: PathBuf,
|
||||
options: Option<DirOperationOptions>,
|
||||
@ -204,7 +216,7 @@ pub async fn read_dir(
|
||||
}
|
||||
|
||||
/// Copies a file.
|
||||
#[cfg(copy_file)]
|
||||
#[cfg(fs_copy_file)]
|
||||
pub async fn copy_file(
|
||||
source: PathBuf,
|
||||
destination: PathBuf,
|
||||
@ -222,7 +234,7 @@ pub async fn copy_file(
|
||||
}
|
||||
|
||||
/// Creates a directory.
|
||||
#[cfg(create_dir)]
|
||||
#[cfg(fs_create_dir)]
|
||||
pub async fn create_dir(path: PathBuf, options: Option<DirOperationOptions>) -> crate::Result<()> {
|
||||
let (recursive, dir) = if let Some(options_value) = options {
|
||||
(options_value.recursive, options_value.dir)
|
||||
@ -240,7 +252,7 @@ pub async fn create_dir(path: PathBuf, options: Option<DirOperationOptions>) ->
|
||||
}
|
||||
|
||||
/// Removes a directory.
|
||||
#[cfg(remove_dir)]
|
||||
#[cfg(fs_remove_dir)]
|
||||
pub async fn remove_dir(path: PathBuf, options: Option<DirOperationOptions>) -> crate::Result<()> {
|
||||
let (recursive, dir) = if let Some(options_value) = options {
|
||||
(options_value.recursive, options_value.dir)
|
||||
@ -258,7 +270,7 @@ pub async fn remove_dir(path: PathBuf, options: Option<DirOperationOptions>) ->
|
||||
}
|
||||
|
||||
/// Removes a file
|
||||
#[cfg(remove_file)]
|
||||
#[cfg(fs_remove_file)]
|
||||
pub async fn remove_file(
|
||||
path: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
@ -269,7 +281,7 @@ pub async fn remove_file(
|
||||
}
|
||||
|
||||
/// Renames a file.
|
||||
#[cfg(rename_file)]
|
||||
#[cfg(fs_rename_file)]
|
||||
pub async fn rename_file(
|
||||
old_path: PathBuf,
|
||||
new_path: PathBuf,
|
||||
@ -286,7 +298,7 @@ pub async fn rename_file(
|
||||
}
|
||||
|
||||
/// Writes a text file.
|
||||
#[cfg(write_file)]
|
||||
#[cfg(fs_write_file)]
|
||||
pub async fn write_file(
|
||||
path: PathBuf,
|
||||
contents: String,
|
||||
@ -299,7 +311,7 @@ pub async fn write_file(
|
||||
}
|
||||
|
||||
/// Writes a binary file.
|
||||
#[cfg(write_binary_file)]
|
||||
#[cfg(fs_write_binary_file)]
|
||||
pub async fn write_binary_file(
|
||||
path: PathBuf,
|
||||
contents: String,
|
||||
@ -316,7 +328,7 @@ pub async fn write_binary_file(
|
||||
}
|
||||
|
||||
/// Reads a text file.
|
||||
#[cfg(read_text_file)]
|
||||
#[cfg(fs_read_text_file)]
|
||||
pub async fn read_text_file(
|
||||
path: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
@ -326,7 +338,7 @@ pub async fn read_text_file(
|
||||
}
|
||||
|
||||
/// Reads a binary file.
|
||||
#[cfg(read_binary_file)]
|
||||
#[cfg(fs_read_binary_file)]
|
||||
pub async fn read_binary_file(
|
||||
path: PathBuf,
|
||||
options: Option<FileOperationOptions>,
|
||||
@ -335,6 +347,7 @@ pub async fn read_binary_file(
|
||||
.map_err(crate::Error::FailedToExecuteApi)
|
||||
}
|
||||
|
||||
#[cfg(fs_path)]
|
||||
pub async fn resolve_path_handler(
|
||||
path: String,
|
||||
directory: Option<BaseDirectory>,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
#[cfg(global_shortcut_all)]
|
||||
use crate::api::shortcuts::ShortcutManager;
|
||||
use crate::{
|
||||
api::shortcuts::ShortcutManager,
|
||||
app::{InvokeResponse, WebviewDispatcher},
|
||||
async_runtime::Mutex,
|
||||
};
|
||||
@ -8,8 +9,10 @@ use serde::Deserialize;
|
||||
|
||||
use std::sync::Arc;
|
||||
|
||||
#[cfg(global_shortcut_all)]
|
||||
type ShortcutManagerHandle = Arc<Mutex<ShortcutManager>>;
|
||||
|
||||
#[cfg(global_shortcut_all)]
|
||||
pub fn manager_handle() -> &'static ShortcutManagerHandle {
|
||||
static MANAGER: Lazy<ShortcutManagerHandle> = Lazy::new(Default::default);
|
||||
&MANAGER
|
||||
@ -34,6 +37,7 @@ pub enum Cmd {
|
||||
IsRegistered { shortcut: String },
|
||||
}
|
||||
|
||||
#[cfg(global_shortcut_all)]
|
||||
fn register_shortcut<A: crate::ApplicationDispatcherExt + 'static>(
|
||||
dispatcher: WebviewDispatcher<A>,
|
||||
manager: &mut ShortcutManager,
|
||||
@ -55,11 +59,11 @@ impl Cmd {
|
||||
self,
|
||||
webview_manager: &crate::WebviewManager<A>,
|
||||
) -> crate::Result<InvokeResponse> {
|
||||
#[cfg(not(global_shortcut))]
|
||||
#[cfg(not(global_shortcut_all))]
|
||||
return Err(crate::Error::ApiNotAllowlisted(
|
||||
"globalShortcut".to_string(),
|
||||
"globalShortcut > all".to_string(),
|
||||
));
|
||||
#[cfg(global_shortcut)]
|
||||
#[cfg(global_shortcut_all)]
|
||||
match self {
|
||||
Self::Register { shortcut, handler } => {
|
||||
let dispatcher = webview_manager.current_webview().await?.clone();
|
||||
|
||||
@ -48,13 +48,16 @@ impl Cmd {
|
||||
#[cfg(http_request)]
|
||||
return make_request(client, *options).await.map(Into::into);
|
||||
#[cfg(not(http_request))]
|
||||
Err(crate::Error::ApiNotAllowlisted("httpRequest".to_string()))
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"http > request".to_string(),
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Makes an HTTP request and resolves the response to the webview
|
||||
#[cfg(http_request)]
|
||||
pub async fn make_request(
|
||||
client_id: ClientId,
|
||||
options: HttpRequestBuilder,
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
use crate::app::InvokeResponse;
|
||||
use serde::Deserialize;
|
||||
#[cfg(notification_all)]
|
||||
use tauri_api::{config::Config, notification::Notification};
|
||||
|
||||
/// The options for the notification API.
|
||||
@ -29,27 +30,28 @@ impl Cmd {
|
||||
pub async fn run(self, context: &crate::app::Context) -> crate::Result<InvokeResponse> {
|
||||
match self {
|
||||
Self::Notification { options } => {
|
||||
#[cfg(notification)]
|
||||
#[cfg(notification_all)]
|
||||
return send(options, &context.config).await.map(Into::into);
|
||||
#[cfg(not(notification))]
|
||||
#[cfg(not(notification_all))]
|
||||
Err(crate::Error::ApiNotAllowlisted("notification".to_string()))
|
||||
}
|
||||
Self::IsNotificationPermissionGranted => {
|
||||
#[cfg(notification)]
|
||||
#[cfg(notification_all)]
|
||||
return is_permission_granted().await.map(Into::into);
|
||||
#[cfg(not(notification))]
|
||||
#[cfg(not(notification_all))]
|
||||
Err(crate::Error::ApiNotAllowlisted("notification".to_string()))
|
||||
}
|
||||
Self::RequestNotificationPermission => {
|
||||
#[cfg(notification)]
|
||||
#[cfg(notification_all)]
|
||||
return request_permission().map(Into::into);
|
||||
#[cfg(not(notification))]
|
||||
#[cfg(not(notification_all))]
|
||||
Err(crate::Error::ApiNotAllowlisted("notification".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(notification_all)]
|
||||
pub async fn send(options: NotificationOptions, config: &Config) -> crate::Result<InvokeResponse> {
|
||||
let identifier = config.tauri.bundle.identifier.clone();
|
||||
let mut notification = Notification::new(identifier).title(options.title);
|
||||
@ -63,6 +65,7 @@ pub async fn send(options: NotificationOptions, config: &Config) -> crate::Resul
|
||||
Ok(().into())
|
||||
}
|
||||
|
||||
#[cfg(notification_all)]
|
||||
pub async fn is_permission_granted() -> crate::Result<InvokeResponse> {
|
||||
let settings = crate::settings::read_settings()?;
|
||||
if let Some(allow_notification) = settings.allow_notification {
|
||||
@ -72,6 +75,7 @@ pub async fn is_permission_granted() -> crate::Result<InvokeResponse> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(notification_all)]
|
||||
pub fn request_permission() -> crate::Result<String> {
|
||||
let mut settings = crate::settings::read_settings()?;
|
||||
let granted = "granted".to_string();
|
||||
|
||||
@ -18,28 +18,30 @@ impl Cmd {
|
||||
command: _,
|
||||
args: _,
|
||||
} => {
|
||||
#[cfg(execute)]
|
||||
#[cfg(shell_execute)]
|
||||
{
|
||||
//TODO
|
||||
Ok(().into())
|
||||
}
|
||||
#[cfg(not(execute))]
|
||||
Err(crate::Error::ApiNotAllowlisted("execute".to_string()))
|
||||
#[cfg(not(shell_execute))]
|
||||
Err(crate::Error::ApiNotAllowlisted(
|
||||
"shell > execute".to_string(),
|
||||
))
|
||||
}
|
||||
Self::Open { uri } => {
|
||||
#[cfg(open)]
|
||||
#[cfg(shell_open)]
|
||||
{
|
||||
open_browser(uri);
|
||||
Ok(().into())
|
||||
}
|
||||
#[cfg(not(open))]
|
||||
Err(crate::Error::ApiNotAllowlisted("open".to_string()))
|
||||
#[cfg(not(shell_open))]
|
||||
Err(crate::Error::ApiNotAllowlisted("shell > open".to_string()))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(open)]
|
||||
#[cfg(shell_open)]
|
||||
pub fn open_browser(uri: String) {
|
||||
#[cfg(test)]
|
||||
assert!(uri.contains("http://"));
|
||||
@ -53,7 +55,7 @@ mod test {
|
||||
use proptest::prelude::*;
|
||||
// Test the open func to see if proper uris can be opened by the browser.
|
||||
proptest! {
|
||||
#[cfg(open)]
|
||||
#[cfg(shell_open)]
|
||||
#[test]
|
||||
fn check_open(uri in r"(http://)([\\w\\d\\.]+([\\w]{2,6})?)") {
|
||||
super::open_browser(uri);
|
||||
|
||||
@ -84,7 +84,7 @@ pub enum Cmd {
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg(create_window)]
|
||||
#[cfg(window_create)]
|
||||
#[derive(Clone, serde::Serialize)]
|
||||
struct WindowCreatedEvent {
|
||||
label: String,
|
||||
@ -95,15 +95,17 @@ impl Cmd {
|
||||
self,
|
||||
webview_manager: &crate::WebviewManager<A>,
|
||||
) -> crate::Result<InvokeResponse> {
|
||||
if cfg!(not(window)) {
|
||||
Err(crate::Error::ApiNotAllowlisted("setTitle".to_string()))
|
||||
if cfg!(not(window_all)) {
|
||||
Err(crate::Error::ApiNotAllowlisted("window > all".to_string()))
|
||||
} else {
|
||||
let current_webview = webview_manager.current_webview().await?;
|
||||
match self {
|
||||
Self::CreateWebview { options } => {
|
||||
#[cfg(not(create_window))]
|
||||
return Err(crate::Error::ApiNotAllowlisted("createWindow".to_string()));
|
||||
#[cfg(create_window)]
|
||||
#[cfg(not(window_create))]
|
||||
return Err(crate::Error::ApiNotAllowlisted(
|
||||
"window > create".to_string(),
|
||||
));
|
||||
#[cfg(window_create)]
|
||||
{
|
||||
let label = options.label.to_string();
|
||||
webview_manager
|
||||
|
||||
@ -13,7 +13,7 @@ use tauri_api::{
|
||||
#[derive(Default, Deserialize, Serialize)]
|
||||
pub struct Settings {
|
||||
/// Whether the user allows notifications or not.
|
||||
#[cfg(notification)]
|
||||
#[cfg(notification_all)]
|
||||
pub allow_notification: Option<bool>,
|
||||
}
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user